# Inferenz-Parität: Gesamtabgleich und Arbeitsliste Stand: 2026-09-05. Arbeitsgrundlage, **keine Freigabe der Performance-Parität**. ## Sicherheitsunterbrechung 2026-09-09: WindowServer-Watchdog Der direkte Lauf `cargo test --release qwen_mtplx -- --include-ignored --test-threads=1` ist **nicht als bestanden belegt**. Der WindowServer-Bericht von 18:13:56 +0200 identifiziert den Testprozess PID 47594 anhand der UUID `2D808BE5-E020-377D-B945-CF7D23FC7BD3` mit 99,07 GiB Footprint. Aktiv war `mtplx_connected_sparse_moe_matches_reference`, CPU-Tensorerzeugung in `pattern_scaled`. WindowServer hing im Metal-/IOGPU-/AGX-Pfad und wurde nach 121 Sekunden ohne Check-in vom Watchdog beendet. Ein Zusammenhang mit diesem Test ist sehr wahrscheinlich; der genaue Grund des Speicheranstiegs und ein bestimmter fehlerhafter GPU-Kernel sind dadurch noch nicht bewiesen. Die Schutzüberwachung von `model-eval` wurde durch den direkten Cargo-Aufruf umgangen. Serielle Ausführung ist kein Speicherlimit. Historische direkte GPU-Testbefehle in diesem Dokument sind daher keine sicheren Wiederholungsbefehle. Der zusätzliche Rust-Launcher `test-supervisor` verwendet dieselbe ausgelagerte `proc_pid_rusage`-Messung wie `model-eval` (`src/process_resources.rs`). Er startet das **vorher gebaute Testbinary direkt**, prüft alle 100 ms Footprint und Lifetime-Peak, beendet bei fehlender Prozessmessung und überwacht Start sowie ausbleibende Ausgabe statt der Gesamtlaufzeit. Grenzen sind explizit; für die isolierte Fehlerdiagnose zunächst 8192 MiB und 15 Sekunden Start/Fortsetzung. Er ist kein Cargo-/Build-Supervisor: Speicherwerte gelten für den Testprozess, nicht beliebige von einem Build erzeugte Prozessbäume. Ausgabe ist nur Testfortschritt, kein Nachweis tatsächlich fortschreitender GPU-Arbeit. Vorbereitung ohne GPU-Ausführung: ```sh cargo build --release --offline --bin test-supervisor -j 1 cargo test --release --offline --bin ds4-server --no-run -j 1 ``` Danach ausschließlich den vom Build ausgegebenen tatsächlichen Testbinary-Pfad an `test-supervisor 8192 15 15 TEST_BINARY mtplx_connected_sparse_moe_matches_reference` übergeben. Keine parallelen GPU-Läufe. Die Speichergrenze ist ein extern geprüftes Abbruchbudget, keine Garantie gegen kurzfristiges Überschießen oder einen nicht unterbrechbaren Treiberfehler. Die unten genannten Leistungsmessungen werden nicht durch diese diagnostischen Grenzen oder Instrumentierung ersetzt. Der betroffene Test meldet vor Gewichtsaufbau, nach Aufbau, nach Verifikation und nach Freigabe Prozess-Footprint, Metal-Allokation sowie aktive/gecachte Allocator-Bytes. Cache, Kernel, Power und Chunkgröße bleiben unverändert. Zusätzlich ist bei Bedarf der vorhandene `DS4_METAL_TRACE_ALLOCS`-Pfad nutzbar. Fortsetzung: - Wächter ohne GPU verifizieren: Speicherabbruch, Start-/Fortsetzungsabbruch, Exitfehler und erfolgreiche Fortsetzung über die Timeoutfenster hinaus. CPU-Selbsttest am 2026-09-09 bestanden (1 Test, fünf Szenarien, 1,66 s). - Erst danach den Speicheranstieg mit isoliertem, überwachtem MoE-Test messen; anhand der vier Grenzwerte aktive Puffer, Cache und übrigen Footprint trennen. - Belegte Ursache im Besitz-/Freigabepfad beheben und Referenzsemantik prüfen. Kein Cache-Leeren oder künstliches Verkleinern als Ersatz für die Diagnose. - Vollständige Qwen-Integration und P16 bleiben offen, ebenso die gesamte Abnahme aller drei Modelle mit/ohne spekulatives Decoding innerhalb 2 %. ### Reproduktion und belegte Ursache, 2026-09-09 Rohdaten: `local-eval-results/moe-memory-20260909.UvC1wv/`. Der Sandbox-Versuch (`test.*.log`) scheiterte vor Ausführung mit „Metal device not available“; alle folgenden Metal-Tests liefen mit freigegebenem Metal-Zugriff und dem externen Wächter. Kein Modell wurde geladen oder heruntergeladen. - Vor Korrektur (`gpu.*.log`): der einzelne ursprüngliche MoE-Test erreicht nach 1,606 s den Speicherabbruch, gemessener Footprint 9.037.880.280 Bytes bei einem Budget von 8.589.934.592 Bytes. Das zeigt auch das mögliche Überschießen zwischen den 100-ms-Abfragen. Bereits der alte Encoderpfad akkumuliert Metal-Speicher; der kanonische Allocator ist noch nicht aktiv. - Zusätzliche vorhandene Allokationsspur (`trace.*.log`, 1-GiB-Budget): Rust/native Tensor-Freigaben bringen den Tensor-Livezähler auf null, während `MTLDevice.currentAllocatedSize` weiter wächst. Kein fehlendes Rust-`drop`, kein MTPLX-Allocator-Cache und kein einzelner großer Kernel ist hierfür nötig. - Minimaler Test `mtplx_tensor_cpu_access_releases_native_storage`, **ohne GPU-Dispatch** (`cpu-red.*.log`): acht 1-MiB-Allokationen pro Zugriffsart. Schreiben, Lesen und `contents` halten jeweils exakt 8.388.608 Bytes über die Tensor-Freigabe hinaus. Anlegen/Freigeben ohne Zugriff, Views, Allocation-Identität und Heap-Abfrage halten jeweils 0 Bytes zurück. Ursache: `MTLBuffer.contents` liefert einen Interior-Pointer. Der mit ARC kompilierte Objective-C-Bridgecode erzeugt dafür `objc_retainAutorelease`; die zusätzliche Referenz bleibt auf einem Rust-Thread ohne passenden Pool-Drain erhalten. Der erzeugte Maschinencode der drei Zugriffe wurde geprüft. Der gepinnte MTPLX-Unterbau ruft `Buffer::raw_ptr()` dagegen über Metal-C++ auf (`mlx/backend/metal/allocator.cpp:25`) und hat diesen ARC-Zusatz nicht. Clang dokumentiert genau diese implizite Lebensdauerverlängerung und ihre Vermeidung durch einen präzise lebenden starken Empfänger: [ARC Interior pointers](https://clang.llvm.org/docs/AutomaticReferenceCounting.html#interior-pointers). Korrektur in `native/metal/ds4_metal.m`: gemeinsamer `ds4_gpu_tensor_cpu_data`-Zugriff mit `objc_precise_lifetime` für die temporäre `MTLBuffer`-Referenz. Der ausdrücklich gehaltene Tensor bleibt Eigentümer des Speichers. `contents`, Read, Write und mittelbar Fill benutzen denselben Pfad. Keine neue Pool-Schleife, keine GPU-Synchronisation, kein Cache-Leeren und keine Änderung von Kernel, Power, Chunkgröße oder Referenz-Testformen. Die Brücke wird auch im Produkt/UI verwendet, nicht nur unter `cfg(test)`. Nach Korrektur: - Identischer Minimaltest (`cpu-green.*.log`) bestanden: alle sieben Zugriffsarten jeweils **0 Bytes** zurückgehaltener Metal-Speicher. Im Maschinencode fehlt nun `objc_retainAutorelease` in den drei Zugriffen; das davon verschiedene `objc_retainAutoreleasedReturnValue` bleibt korrekt. - Ursprünglicher MoE-Test (`fixed.*.log`), unverändertes 8-GiB-/15-s-Budget: **440 exakte Referenzvergleiche**, 220 je Encoder, abgeschlossen in 13,322 s. Peak-Footprint 4.839.182.320 Bytes (4,51 GiB). Nach jedem der 220 alten Encoderfälle genau 1.769.472 Bytes Metal-Basisbelegung. Im kanonischen Encoder nach Freigabe 0 aktive Allocator-Bytes; am Ende 3.202.034.186 Bytes regulärer Cache. Dieser Cache wurde nicht künstlich geleert. - Originalquellprüfung bestanden: 17 Körper, 41 Custom-Einstiegspunkte, 22 Runtime-Einheiten / 203 Einstiege plus dynamische QSA-Quellen stimmen mit dem gepinnten Export überein. - Alle drei Puffer-Eigentumstests bestanden (`ownership.*.log`, 0,08 s): Completion hält Allokationen ohne Data-Donation zu verändern, leere Tensoren/Views behalten ihre Identität, CPU-Zugriffe behalten keinen Speicher. Release-Testbuild, warnings-denied Clippy für App und Tests sowie `cargo fmt --all -- --check` und `git diff --check` bestanden. Dies behebt die reproduzierte Retention, ist aber **keine** abgeschlossene UI-Responsiveness- oder 2%-Performance-Abnahme. Ein vollständiger neuer UI-/Harness-/Golden-Master-Vergleich und die übrige Qwen-Portierung bleiben offen. ## Verbindliche Auftragspräzisierung vom 2026-09-06 Die bisherige Auswahl einzelner Optimierungen anhand von Mikrobenchmarks wird beendet. Der Nutzer verlangt für Qwen einen vollständigen MTPLX-Port, keine Sammlung ähnlich wirkender Rust-/Metal-Optimierungen. Diese Präzisierung hat Vorrang vor früheren Auswahl- und Rücknahmebegründungen in diesem Dokument. - **Kernel-Identität:** Die im gepinnten MTPLX-Qwen-Pfad tatsächlich verwendeten Metal-Kernel übernehmen, einschließlich der von dessen gepinnten Abhängigkeiten bereitgestellten Kernel. Gleiche Typen, Layouts, Spezialisierungen, Geometrien, Rundungs-/Reduktionsfolgen und Dispatch-Bedingungen. Eigenständige MPP-QMM- Implementierungen sind kein Ersatz für die von MTPLX aufgerufenen Kernel, auch wenn einzelne Ausgabehashes passen. Nur erforderliche ABI-/Binding- Anpassungen separat ausweisen; keine stillen algorithmischen Änderungen. - **Rust-Funktionsidentität:** Modellaufbau, Materialisierung/Fusion, Graphfolge, PLE-Streaming, Cache-/State-Lebenszyklus, Scheduling, Sampler, MTP-Draft/Verify/ Commit/Repair sowie EOS/Cancel und Fortsetzung vollständig nachbilden. Dazu gehören alle für das vorhandene Modell erreichbaren Form- und Fallbackzweige, nicht nur die von drei Beispielprompts zufällig ausgeführten Pfade. - **Zusammenhängende Umsetzung:** P01–P12 sind Abdeckungs- und Portierungsaufgaben, keine optionalen Optimierungskandidaten. Zuerst deren vollständige Referenz- Zuordnung und Umsetzung samt Korrektheits-/State-Tests. Anschließend den integrierten Stand gegen MTPLX auf Gesamtlaufzeit, Durchsatz und Verzögerungen prüfen. Kein erneuter Performance-Auswahlzyklus nach jedem Kernel. - **Rücknahmen:** Ein isoliert fehlender Geschwindigkeitsgewinn ist kein Rücknahmegrund für einen korrekten Referenzport. Nur belegte harte Regressionen rechtfertigen eine begründete Rücknahme; der betroffene Referenzbestandteil bleibt dann ausdrücklich unerledigt. Ein Eigenbau-Experiment zurückzunehmen beweist nicht, dass die entsprechende MTPLX-Implementierung verzichtbar ist. - **Abnahme:** Erst vollständige funktionale und Kernel-Abdeckung, dann P16 mit den vereinbarten vollständigen Chats und Referenzvergleichen. DeepSeek/GLM behalten antirez/ds4 als Golden Master und bleiben Teil des Gesamtziels. Insbesondere werden die früheren negativen Einzelversuche zu P07 (Gate/Up- Fusion), P09 (Matmul-Layouts) und P11 (lazy Target-Verteilungen) **nicht** als Freistellung von der entsprechenden MTPLX-Funktionalität verwendet. Historische Messbelege bleiben erhalten, entscheiden aber nicht über den Umfang des Ports. ### Quellzuordnung für die zusammenhängende Qwen-Portierung Dies sind geprüfte Einstiegspunkte, noch keine vollständige Kernel-Abdeckung. Für jeden Bereich ist die transitive Zuordnung bis zum tatsächlichen Kernel einschließlich aktivierter Laufzeit-/Formbedingungen zu schließen. Ein Import allein oder ein gesetztes Flag gilt nicht als Dispatch-Nachweis. | Bereich / bestehender Task | MTPLX-Einstieg | Verbindlicher Umfang | | --- | --- | --- | | Modell / Laden / Typen · P01/P09 | `models/qwen4_exp.py`: `TextModel`, `Qwen4ExpTextModel`, Sanitize-Fusionen | Gewichte, BF16-Aktivierungen, FP32-Zustände, zusammengeführte Projektionen, Views und Lebensdauer | | Hyper-Connections · P09 | `GatedResidual`, `kernels/hyper_connection_v3.py`, `hyper_connection.py` | R1/R2, vorbereitete Quantisierung, Prefill- und Fallbackpfade, nicht nur Decode | | Affine / Gather / Sorted Matmul · P07/P09 | `_FusedGDNInProj`, `_FusedGateUpSwitchGLU`, `_FusedGateUpMLP`; deren tatsächlich aufgerufene Quantized-Matmul-Kernel | QMV/QMM/NAX/Split-K, Gather/Sort/Unsort, gemeinsame Gate/Up-Projektionen, Typ-/Formgrenzen | | GDN · P06 | `GatedDeltaNet.__call__`, `kernels/gdn_step_fused.py`, `gdn_conv_norm.py`, `gdn_out_fused.py`; `gated_delta_update` aus der gepinnten Abhängigkeit | Vollständige Branchfolge, Conv-/Delta-Zustände, Capture-Tape, Norm/Gate, Prefill/Decode/Verify | | MoE / Shared Expert · P07 | `SparseMoeBlock`, `_FusedGateUpSwitchGLU`, `_FusedGateUpMLP`, `kernels/moe_glu_decode.py` | Router, Top-k, Sortschwelle, fusionierte Decode-/Verify- und Prefillpfade, Shared-Expert-Kombination | | QSA / KV / Attention · P08 | `Attention`, `QSAIndexer`, `QSACache`, QSA-Kernelmodule und tatsächlich selektierter Attention-Backendpfad | Cache-Layout, Pooling/Indexer/Top-k/Masken, Dense-/Sparse-/Gather-/Flashzweige, Kontextgrenzen | | PLE · P10 | `NGramTable`, `_SidecarGather`, `NGramEmbedding`, `PLELayer` | Hashing, Vorab-Staging, LRU/Bypass, Gather-/IO-Reihenfolge, Faltung und History | | Serving / Sampling / MTP · P02–P05/P11/P12 | `server/openai.py`, `sampling.py`, Modell-Capture und aufgerufene Generator-/Backendmodule | Tokenisierung, laufender Chat, RNG/Verteilungen, Draft/Verify, Commit/Repair, Cache, Submission und Abschluss | Der bestehende Rust-Pfad in `src/engine/metal/qwen.rs` und die Kernel in `metal/qwen38.metal` sind gegen diese gesamte Kette zu ersetzen/anzugleichen. Die Referenz bleibt MTPLX; seine verwendeten Bibliothekskernel sind Bestandteile dieser Referenzausführung, kein Wechsel zu einem anderen Golden Master. ### Portierungsstand: unveränderte Kernelkörper und direkte Bindung 2026-09-06: `metal/mtplx_qwen.metal` enthält erstmals direkt extrahierte, unveränderte MTPLX-Kernelkörper, nicht nachgeschriebene Äquivalente. `tools/mtplx-kernel-source.py` prüft den sauberen Referenzcommit und erzeugt die deterministische Übersetzungseinheit. `--check` vergleicht die gesamte Datei; ein gewöhnlicher Rust-Test schützt zusätzlich die neun eingebetteten Körperhashes. Nur Einstiegspunkt-ABI und Templatespezialisierungen sind außerhalb der Körper ergänzt. BF16 ist physisch BF16, der RMS-/Delta-Zustand bleibt wo vorgesehen FP32. | MTPLX-Körper | Eingebundene Spezialisierungen | Korrektheitsbeleg | Produktgraph | | --- | --- | --- | --- | | `hyper_connection._SOURCE` | BF16, Injection0/1 | Zeilen1/4/8, Ausgabehashes exakt | Umstellung offen | | `hyper_connection_v3._SRC_R1` / `_SRC_R2` | BF16, RMS FP32 | Gekoppelte R1/R2-Ausgabe exakt | Umstellung offen | | `gdn_conv_norm._SRC` | BF16 | q/k/v und Folgezustand exakt | Umstellung offen | | `gdn_conv_norm._SRC_ROWS` | BF16, S2–6 | Alle fünf Breiten, q/k/v und Folgezustand exakt | Umstellung offen | | `gdn_step_fused._SRC` | BF16, Rekurrenz FP32 | Zwei aufeinanderfolgende Schritte einschließlich beider Folgezustände bitgenau | Umstellung offen | | `gdn_out_fused._SRC` | Gruppen32/64, x BF16/FP32, Quantparameter BF16 | Alle vier Kombinationen bitgenau, synthetische gültige Q4-Packs | Umstellung offen | | `mlx_lm 0.31.3/models/gated_delta.py` · skalare Rekurrenz | BF16 q/k/v/beta, FP32 g/Zustand; mit/ohne Maske | S1/4/7/32/2048, Ausgabe und FP32-Folgezustand bitgenau | Umstellung offen | Die Metal-Bibliothek lädt diese 17 Einstiegspunkte. Die neue direkte Bridge bindet geordnete Ein-/Ausgabepuffer ohne eigenes Qwen-Argumentlayout, Typcasts, automatische Geometrieänderung oder zusätzliche Flushes. Ihre Bindungs-/Grid- Konvention wurde gegen den [gepinnten CustomKernel-Dispatcher](https://raw.githubusercontent.com/ml-explore/mlx/v0.32.2/mlx/backend/metal/custom_kernel.cpp) geprüft; das ist MTPLXs benutzte Runtime, kein anderes Modell-Orakel. R1/R2 samt Packvorbereitung bleiben im Test nachweislich in einem Command Buffer. Der vorhandene Stage-Profiler verwendet für alte/neue Aufrufe dieselbe Erfassungsfunktion. Allgemeine Submission-/Ressourcenparität P05 bleibt offen. `tools/mtplx-kernel-fixtures.py` ruft die tatsächlichen MTPLX-Funktionen mit modellfreien deterministischen Eingaben auf. Die 29 geprüften Fälle mit 65 Ausgabehashes stehen in `tests/fixtures/mtplx-custom-kernels.jsonl`. GPU-Test und CPU-Quellhash-Test bestanden; keine Benchmarks oder vollständigen Modellläufe. Apache-Lizenz und NOTICE mitgeliefert; Attribution im CLI und verlinkt in den Modelleinstellungen. **Keine Fertigmeldung:** Der Inferenzgraph ruft derzeit weiterhin die alten Kernel auf; die direkte ABI wird bisher vom Korrektheitstest genutzt. Die zusammenhängende Umstellung der Aktivierungen und Graphaufrufe auf BF16 sowie die übrigen MTPLX-Kernel und Rust-Funktionen sind weiterhin umzusetzen. Kein FP32/BF16-Konvertierungsadapter wurde als vermeintlich fertiger Port eingeführt. Diese Grundlage ist keine Performance- oder Gesamtparitätsabnahme. Die Rekurrenzquelle stammt aus MTPLXs tatsächlich installiertem `mlx-lm 0.31.3`, SHA256 `79c8376a51c694b03e54d2f996ced6ea6c8c42868b8571529f97334db165a3e1`. Der Exporter wertet ausschließlich die String-/F-String-AST aus, nicht den Python-Modellcode. Die tatsächlich generierte Referenzsignatur wurde separat mit `verbose=True` geprüft: Skalar `T` als `constant int32_t&`, Grid32×128×48, Threadgroup32×4×1. Ihre MIT-Lizenz ist mitgeliefert. Der FP32-Zustand wird im Test nicht auf BF16 reduziert; die bisherigen 19 Fixture-Zeilen blieben unverändert. Für die folgenden Matmul-Ports ist nun auch die **exakte Runtime-Quelle0.32.2** lokal vorhanden: `local-eval-results/mtplx-runtime-0.32.2`, Commit `1f8e74e3f12f31365464a6867c6579f0e9b29d85`. `quantized.h` stimmt byteweise mit dem installierten Referenzheader überein. Die ältere Navigation über die lokale 0.32.3-Kopie ist keine Portierungsfreigabe. Der unveränderte Upstream-Generator `make_compiled_preamble.sh` scheitert innerhalb und außerhalb der Sandbox an der fehlenden separaten Metal-Toolchain; die Metal-Laufzeitkompilierung funktioniert. Keine Toolchain installiert, kein Host-C/C++-Backend gebaut, keine Modelle geladen. Die Runtime enthält außerdem ihre vorhandene `mlx.metallib`; deren Nutzung oder quellidentische Neuerzeugung war zu diesem Zeitpunkt noch offen. Der folgende Abschnitt dokumentiert die inzwischen geprüfte direkte Shader-Nutzung. ### Runtime-Shader und verbundener BF16-GDN-Abschnitt Die installierte Runtime wurde nicht nur anhand der Versionsnummer eingeordnet: `get_quantized_kernel` in ihrer tatsächlichen `libmlx.dylib` ruft direkt `Device::get_kernel` für die vorgefertigte Standardbibliothek auf (Disassembly bei0xd8af40). Das entspricht `nojit_kernels.cpp` der gepinnten0.32.2-Quelle. Die dort vorhandene Shader-Datei ist deshalb **byteidentisch** als `metal/mtplx-runtime-0.32.2.metallib` übernommen; SHA256 `dc59d1cceb1a5c7e578232e6e41e28e2c73c9463ac6dbc3886c3ee17ffc270ed`, 182351120Bytes. Kein C/C++-Backend wird eingebunden. Lizenztext und Herkunft stehen in `metal/MLX-LM-LICENSE.txt` und `metal/MTPLX-RUNTIME.txt`. Die vorhandene Ressourcenverpackung nimmt die Datei mit auf; die Metal-Bridge lädt sie erst beim ersten entsprechenden Dispatch. Keine Toolchain-Installation. `src/engine/metal/qwen_mtplx.rs` enthält jetzt die direkten Rust-Aufrufe für kontiguierliche, nicht gebatchte BF16-Affine-Projektionen auf dem M5Max: - Referenzgrenzen33/25/13 nach Matrixdimension, QMV-Quad, normale/schnelle QMV, QMV-Wide inklusive Referenz-Tiling statt einer eigenen Zeilenheuristik. - QMM, NAX und Split-K einschließlich **BF16**-Teilresultaten und den originalen ein-/zweistufigen Reduktionskerneln. Integerparameter über `setBytes`, explizite 3D-Threadgroups; keine CPU-Reduktion oder Typkonvertierung. - 78 gegen tatsächliche `mx.quantized_matmul`-Aufrufe erzeugte Fälle bitgenau: Bits4/8, Gruppen32/64, Randgrößen, Variantengrenzen, beide Reduktionsstufen, NAX-/Steel-Pfade und 2048Zeilen. Diese Runtime-Aufrufe sind Bestandteile der MTPLX-Referenz, keine Änderung des Modell-Orakels. - Verbundener GDN-Decode-Abschnitt: fusionierte Eingangsprojektion → originaler GDN-Step → Ausgangsprojektion, native BF16-Views und getrennte neue Conv-/Delta- Zustände. Zwei Folgeschritte stimmen vollständig mit dem tatsächlichen `GatedDeltaNet.__call__` aus MTPLX überein. Der Referenztest prüft ausdrücklich dessen Live-State-Branch; Kaltstart/Prefill/Verify sind damit nicht abgenommen. Jeder Rust-Schritt verbleibt nachweislich in einem Command Buffer. Die direkte Bridge hält Datenbindung und Pipeline-Bool-Konstanten getrennt, prüft ungültige/überlappende Bindungen und verwendet die bestehenden Metal- Command- und Profiling-Funktionen. Temporäre Projektions-/Split-Puffer bleiben im Rust-Ergebnis bis zum Abschluss des Command Batches erhalten. **Produktstatus unverändert offen:** Das neue Rust-Operationsmodul ist bis zur zusammenhängenden BF16-Graphmigration ausdrücklich unter `cfg(test)` eingebunden. Es ersetzt noch nicht den alten FP32-Inferenzgraphen. Es ist kein zweiter Generator und keine abweichende Headless-Engine. MoE/Gather/Sort, QSA/Attention, PLE, komplette GDN-Fallback-/Capture-Pfade sowie Sampling/MTP und der gemeinsame Zustands-/Scheduling-Port sind weiterhin umzusetzen. Kein P01–P16 geschlossen, keine Geschwindigkeitsmessung, Bundle-Auslieferung oder Paritätsabnahme. Die Fixture-Datei enthält nun insgesamt 571 Fälle mit 797 Ausgabehashes. Die bisherigen 546 Fälle blieben beim ergänzenden Normmodul-Nachweis unverändert. Zusätzliche CPU-Tests prüfen den Shader-Dateihash und die Rust-Dispatch-Grenzen. ### Gather-Dispatch: geprüfter Portabschnitt, keine Produktabnahme `qwen_mtplx::gather_bf16` bildet den normalisierten BF16-Gather-Pfad in Rust ab: QMV normal/fast, Gather-QMM Steel/NAX sowie sortiertes RHS-QMM mit den originalen Bool-Konstanten200/201/202. Es benutzt ausschließlich die unveränderte gepinnte Runtime-Metallib. MTPLX sortiert ab64Routen; der Backendwechsel zum sortierten RHS-Kernel erfordert separat M=1, mindestens16Routen und Routen/Experten>=4. Die NAX-RHS-Tilehöhe wechselt bei Routen/Experten=64 von32 auf64. Diese Bedingungen sind keine lokalen Performance-Heuristiken. GPU-Sortierung und Rücksortierung sind dadurch ausdrücklich noch nicht implementiert. 40 echte `mx.gather_qmm`-Referenzaufrufe prüfen Q4/Q8, Gruppen32/64, allgemeine und sortierte Indizes, die Schwellen unmittelbar darunter/darüber, N-Ränder sowie 512Experten. Alle40Ausgaben sind bitgenau. Der gemeinsame fokussierte Lauf führte7Tests aus:7bestanden,0fehlgeschlagen,0ignoriert;149GPU-Fälle/189Hashes. **Referenzfehler im künstlichen K-Randfall:** Bei sortiertem X=33,M=1,N=81,K=160,E=8,R=33 liest der gepinnte NAX-RHS-Kernel über logische Tensorgrenzen. Bereits MTPLX allein liefert bei unveränderten logischen Eingaben andere Ergebnisse, wenn nur nachfolgender Speicher geändert wird. In `quantized_nax.h:1659` wird die letzte A-Tilebreite aus BK statt k_remain gebildet; Eingangs-Padding allein genügte im gesamten Fixture-Lauf nicht, erst kontrollierte physische Grenzen auch für W/Skalen/Biases machten beide Ausführungen identisch. Die zwei betroffenen Q4/Q8-Fälle sind deshalb mit explizitem Nullpadding in beiden Testläufern enthalten, nicht übersprungen oder toleranzgeweitet. Die übrigen 38Gather-Ausgabehashes blieben unverändert. Originalkernel und Produktionspuffer wurden nicht geändert. Diese synthetische K=160-Form ist keine MoE-Form des installierten Modells (K=2560 bzw.640). Beleg und ursprüngliche Hashes stehen in `local-eval-results/20260906-mtplx-port/gather-padding-investigation.md`. Der Produktgraph bleibt unverändert offen; diese Checks ersetzen weder die MoE-Kette noch die sechs abschließenden Gesamtmessungen. ### GPU-Argsort und inverse Reihenfolge Der normalisierte Rust-Argsort für zusammenhängende letzte Achsen verwendet die originalen Runtime-Kernel für U32-, BF16- und FP32-Eingaben. Die Referenz führt auch `argpartition` als vollständigen Sort aus. Übernommen sind die Auswahl der 32/64/128/256/512-Thread-Blöcke, Vierer-Tiles, Mehrblock-Sortierung mit Werte- und Index-Pingpong, Partition/Merge-Reihenfolge und der abschließende Original-Copy. Die Copy-Variante wechselt bei65536Elementen von1 auf2Elemente pro Thread. Die Metal-Bindung unterstützt dafür zusätzlich `dispatchThreads`; aufgerundete Threadgroups wären bei diesem ungeschützten Copy-Kernel nicht funktionsidentisch. Bestehende Matmul-/Gather-Aufrufe verwenden weiter unverändert Threadgroups. 123 echte Referenzaufrufe prüfen jeweils `argsort(x)` und `argsort(order)`: 20Breiten von1 bis65537 bei1/3Zeilen, dazu2048x512; jeweils U32/BF16/FP32. Die Daten enthalten gleiche Werte, auch durch BF16-Rundung entstandene Gleichstände. Alle246Index-Hashes sind bitgenau. Beide zusammenhängenden Sortierungen samt Merge-/Copy-Schritten bleiben in jedem Rust-Test in genau einem Command Buffer; kein CPU-Auslesen zwischen den Sortierungen. Der gemeinsame Lauf hat8Tests ausgeführt:8bestanden,0fehlgeschlagen,0ignoriert,272Fälle/435Ausgabehashes. Rohbeleg: `local-eval-results/20260906-mtplx-port/runtime-sort-combined-check.log`. Damit ist die inverse **Indexreihenfolge** geprüft, nicht schon die vollständige `_gather_sort`-/`_scatter_unsort`-Datenbewegung. Deren Division/Gather-Front-Aufrufe, die verbundene MoE-Kette und die übrige Produktgraphmigration bleiben offen. Keine Gesamtperformance-Abnahme, kein P01–P16 geschlossen. ### Verbundene Sort/Gather/Unsort-Datenbewegung Die zuvor offene Datenbewegung ist nun als zusammenhängender Rust-Abschnitt implementiert: Experten-Argsort, inverse Reihenfolge, `order // top_k`, Gather der BF16-Tokenzeilen und U32-Expertenindizes, anschließend Gather über die inverse Reihenfolge für die Rücksortierung. Keine CPU-Auswertung der erzeugten Indizes. Die Sortschwelle gehört weiterhin in den noch zu verbindenden MoE-Aufrufer. MTPLXs Runtime erzeugt den Gather-Front-Kernel aus `indexing/indexing.h` und `indexing/gather_front.h` zur Laufzeit. Diese Shader-Einheiten werden jetzt mit gepinnten Datei- und Einheitshashes unverändert in die vorhandene kanonische Quelldatei exportiert; nur Includes werden aufgelöst und Instanziierungen ergänzt. Keine C++-Hostimplementierung übernommen. Die bestehende Bindung kann diese Shader mit unmittelbaren Größen-/Stride-Parametern aufrufen und behält originale `dispatchThreads`-Geometrie und Zwei-Elemente-Grenze bei BF16-Slicegröße>8 bei. Die ganzzahlige Division nutzt die unveränderte Runtime-Metallib mit dem Referenzwechsel der Arbeit pro Thread bei65536Elementen. Sieben direkte Aufrufe der tatsächlichen MTPLX-Helfer `_gather_sort` und `_scatter_unsort` sind mit vier Ausgaben pro Fall geprüft: sortierte Daten, Expertenindizes, inverse Reihenfolge und zurücksortierte Daten. Fälle:1/6/7/205/ 2048/6554Tokens bei Top-10, Breiten7/8/9/2560, darunter2048x10x2560 und eine 65540-Routen-Kette. Alle28Hashes sind bitgenau. Jede gesamte Rust-Kette bleibt in einem Command Buffer. Der gemeinsame Lauf führt9Tests aus:9bestanden,0Fehler, 0ignoriert;279Referenzfälle/463Hashes. Alle bisherigen272Fixture-Zeilen waren bei frischer Referenzerzeugung unverändert. Der Quellvergleich prüft außerdem die9Custom-Bodies/17Einträge sowie2Runtime-Einheiten/8Gather-Instanziierungen; die geketteten Tests betreffen BF16/U32 mit32-Bit-Offsets, nicht alle8Varianten. Beleg: `local-eval-results/20260906-mtplx-port/connected-gather-combined-check.log`. **Weiter offen:** verbundene Gate/Up-Aktivierung/Down-MoE-Kette, Router/Shared- Expert-Integration, die übrigen Graphabschnitte und die vollständige BF16- Produktmigration. Keine Performance-Abnahme oder Änderung der Abschlusskriterien. ### Verbundene SwitchGLU-Rechenkette und tatsächlicher SiLU-JIT-Code `qwen_mtplx::switch_glu` bildet jetzt den vollständigen Aufruf von `_FusedGateUpSwitchGLU` mit bereits ausgewählten Experten ab: Sortierung ab64Routen, gemeinsame Gate/Up-Gather-Projektion, `nn.silu(gate) * up`, Down-Gather-Projektion und Rücksortierung. U32-Arange und Broadcast-Strides erhalten die implizite Token-/Expertenzuordnung; kein zusätzliches Materialisieren broadcasteter Tokenindizes, kein CPU-Auslesen erzeugter Indizes. Aktivierungen bleiben BF16. Temporäre Puffer werden bis zum Abschluss des zusammenhängenden GPU-Batches gehalten. Der SiLU-Code wurde nicht anhand seiner Formel neu geschrieben: `tools/mtplx-jit-reference.py` beobachtet im isolierten Referenzprozess den originalen Objective-C-Metal-Compileraufruf, leitet ihn unverändert weiter und setzt den lokalen Beobachtungs-Hook abschließend zurück. Der gespeicherte JIT-Receipt `tests/fixtures/mtplx-silu-jit.json` enthält alle19erzeugten Varianten. Vollständiger beobachteter Compiler-Quellhash: `76cafb45db55a91efba66503dde59b37628ea360f220f35dd860f4ac3c3d0111`. Die Rank-2-Erzeugung wurde erneut exakt bestätigt; Rank3/5 der sortierten und unsortierten SwitchGLU erzeugen nach Normalisierung der Symbolnamen denselben Rechencode. Keine Rechenanweisung wird durch diese Normalisierung geändert. Der bestehende Shader-Exporter übernimmt diese19Varianten sowie ihre originalen BF16-Mathematik-, Sigmoid-, Multiply-, Cast- und Stride-Helfer mit gepinnten Dateihashes. Nur die Hostnamen erhalten lokale Aliasse. Das ist Shadercode, kein übernommener C++-Hostcode. Die Rust-Auswahl erhält Contiguous/Strided-Pfade, die65536-Elemente-Grenze und den separaten ursprünglichen Up-Multiply-Dispatch. Der Quellcheck umfasst nun9Custom-Bodies/17Einträge sowie8Runtime-Einheiten mit 27Runtime-Einträgen (8Gather,19SiLU). Nachweise:10Aktivierungsfälle mit zwei Ausgaben, darunter20480x640 und die Vektorisierungsgrenzen;21direkte Aufrufe der tatsächlichen MTPLX-SwitchGLU-Klasse mit synthetischen Q4-Gewichten, Gruppen32/64/gemischt. Ganze Ketten bei1/6/7/205/ 2048Tokens mit K2560/I640/E16 sowie7/205Tokens mit K128/I64/E512. Alle41neuen Ausgabehashes bitgenau; jede Rust-Kette ein Command Buffer. Der gemeinsame Lauf: 11Tests ausgeführt,11bestanden,0fehlgeschlagen,0ignoriert;310Fälle/504Hashes. Beleg: `local-eval-results/20260906-mtplx-port/connected-switch-combined-check.log`. Das ist keine Messung des vollständigen512Experten-Modells bei K2560. **P07 bleibt offen:** Router/Softmax/Top-k, Gewichtung, Shared Expert und die gesonderten fusionierten Decode-/Verify-Pfade von `SparseMoeBlock` sind nicht durch den abgeschlossenen SwitchGLU-Untermodul-Nachweis abgedeckt. Auch die übrigen Graphabschnitte, Produktintegration und Gesamtperformance-Abnahme bleiben offen. Kein Rollback und keine Auswahl von Teiloptimierungen nach Geschwindigkeit. ### Verbundener Router und SparseMoeBlock einschließlich Decode/Verify Der kanonische Rust-Port umfasst jetzt den Standard-MoE-Block mit den Sanitize-fusionierten Expert-/Shared-Expert-Packs: Q8-Routerprojektion, präzises BF16-Softmax über alle Experten, vollständiges Argpartition/Argsort, Top-10-View, GatherAxis und optionale Normalisierung, SwitchGLU, gewichtete BF16-Summe, Shared-MLP, Sigmoid-Gate und Addition. Der Top-10-Stride bleibt erhalten; erst das originale Flatten vor Sortierung materialisiert ihn. Unsortiertes GatherQMM verarbeitet ihn direkt. Keine CPU-Indizes oder zusätzlichen Flushes/Wartepunkte innerhalb der verbundenen Kette. Die vier unveränderten Kernelkörper aus `moe_glu_decode.py` sind zusätzlich mit16BF16-Spezialisierungen eingebunden: Decode und Verify mit2/3/4Zeilen, Gruppen32/64 für Gate-Up und Down unabhängig. Die beiden Referenzflags sind standardmäßig aus; ihre aktivierten Zweige einschließlich BF16→FP32-Routengewichten, Shared-Expert-Kombination und Rückfall bei mehr als4Zeilen sind im selben Rust-Dispatcher portiert. Keine Auswahl anhand eines Teilbenchmarks. - 16 Routerfälle mit 48 Hashes, einschließlich 2048x512 sowie 4096/4097-Softmaxgrenze. - 48 vollständige Standard-MoE-Fälle gegen die tatsächliche MTPLX-Klasse. - 64 weitere Klassenaufrufe mit beiden Fusionsflags aktiv: Decode/Verify, Gruppenkombinationen und5/7-Zeilen-Fallback. Optionale Normalisierung jeweils an/aus. - Modellabmessungen K2560/I640/E512 sind im Standardpfad bei 1/7/2048 Zeilen und in den fusionierten Pfaden bei1/4Zeilen enthalten; synthetische Gewichte, kein vollständiger Modelllauf. Alle Ausgabehashes bitgenau. Gemeinsamer Prüflauf:13Tests ausgeführt,13bestanden,0fehlgeschlagen,0ignoriert; 438Fälle/664Hashes. Jede verbundene Testkette bleibt in einem Command Buffer. Der Quellcheck umfasst13Custom-Bodies/33Einträge und10Runtime-Einheiten mit 35Einträgen; GatherAxis und dessen Stride-Helfer werden unverändert übernommen. Beleg: `local-eval-results/20260906-mtplx-port/connected-moe-combined-check.log`. **Weiter offen:** Diese Operationen bleiben `cfg(test)`. Der alte Produktgraph wurde nicht auf diesen Stand umgestellt. P07 umfasst außerdem die nicht Sanitize-fusionierten Modulpfade; die übrigen Graphabschnitte, State/Cache, Submission und die zusammenhängende BF16-Produktmigration bleiben offen. Exakte Blockausgaben beweisen weder Scheduling-Parität des vollständigen Modells noch UI-Responsiveness oder Gesamtperformance. P01–P16 nicht geschlossen. ### Getrennte MoE-Projektionen und verbundene Normmodule Der kanonische MoE-Dispatcher bildet nun auch `SwitchGLU` und `Qwen3NextMLP` ohne Sanitize-Fusion ab. Expert- und Shared-MLP können unabhängig zusammengepackt oder getrennt vorliegen; getrennte Gate-/Up-Projektionen behalten ihre eigenen Quantisierungsgruppen und ihre ursprüngliche Aufrufreihenfolge. Die fusionierten Decode-/Verify-Kernel werden bei separaten Experten trotz aktivierter Flags wie in MTPLX nicht gewählt. Keine Änderung an der Standard-Flagbelegung. Der ursprüngliche `swiglu`-Compileraufruf wurde mit dem bestehenden lokalen Beobachter erfasst. Receipt `tests/fixtures/mtplx-swiglu-jit.json`, voller beobachteter Quellhash: `bf78eee5cf96ea7c112c4e61546c12bcacf57fe512e0572182604cb94137510b`. Alle 19 erzeugten Varianten sind unverändert mit lokalen Host-Aliassen exportiert. Rank-3 und Rank-5 liefern nach reiner Symbolnormalisierung denselben Rechencode. Anders als beim fusionierten Pack ist SwiGLU hier ein gemeinsamer kompilierter Aktivierungs-/Multiply-Aufruf mit zwei separaten Projektionseingaben. 108 zusätzliche Aufrufe der tatsächlichen MTPLX-MoE-Klasse prüfen getrennte und gemischte Modulbelegungen, Gruppen 32/64, Normalisierung an/aus, Sort-/Matmul- Grenzen und aktivierte Fusionsflags. Darunter E512/K2560/I640 mit 1/7/2048 Zeilen. Alle 108 Ausgabehashes sind exakt; die bisherigen 438 Fixtures blieben unverändert. Außerdem sind `GroupedRMSNorm` (HC/PLE) und `SigmoidRMSNormGated` (GDN) als verbundene Rust-Operationen mit den unveränderten Runtime-Shadern portiert. Erhalten bleiben ungewichtete Gruppen-RMS vor separater Vollbreitengewichtung, BF16-Rundung vor dem FP32-Sigmoid-/Multiply-Epilog, fehlendes Gate sowie das strided Z-View aus der fusionierten GDN-Eingangsprojektion. 25 direkte Aufrufe der tatsächlichen Normklassen sind exakt, einschließlich 2K Zeilen, Loop-/ Vektorisierungsgrenzen und GDN-Zeilenstride 16480. Das ist noch nicht der komplette gestufte GDN-Forward einschließlich Conv, compute_g, Rekurrenz und Capture-State. Gemeinsamer Lauf: 14 Tests bestanden, 0 fehlgeschlagen, 0 ignoriert; 571 Fälle / 797 exakte Hashes. Jede verbundene Kette bleibt in einem Command Buffer. Quellcheck: 13 Custom-Körper / 33 Einträge, 11 Runtime-Einheiten / 54 Einträge. Beleg: `local-eval-results/20260906-mtplx-port/separate-moe-norm-combined-check.log`. P07 bleibt wegen der Produktintegration offen. P06/P08/P09/P10 sowie die übrigen Host-/State-/Scheduling-Aufgaben bleiben offen; keine Gesamtperformance-Abnahme. ### Verbundener gestufter GDN-Forward und compute_g `gated_delta_update` ist einschließlich des tatsächlichen kompilierten `compute_g`, BF16-Sigmoid, initialem FP32-Nullzustand, Maske und ursprünglicher Rekurrenz verbunden. Das JIT-Receipt bewahrt alle 19 erzeugten Varianten; BF16-Add/LogAddExp vor den FP32-Exponentialoperationen bleibt unverändert. 80 direkte Referenzaufrufe mit zwei aufeinanderfolgenden Updates prüfen kalte/vorhandene Zustände, Masken und A/B-Zeilenstride 48/16480 bis 2K Zeilen. Alle 320 Hashes sind exakt. Der gestufte `GatedDeltaNet`-Forward mit fusionierter Eingangsprojektion ist jetzt bis zur Ausgangsprojektion verbunden: QKV-Maske, Conv-Zustandskonkatenation, Tail beziehungsweise geklippte Cache-Längen mit originalem INT32-GatherAxis, ursprüngliche Depthwise-Conv1D, SiLU, FP32-L2-Normalisierung mit BF16-Grenze vor Q-Skalierung, Rekurrenz, Sigmoid-RMS und Ausgangsprojektion. Die Conv-Norm- Fusionen für S1/S2–6 und die Output-Fusion behalten ihre Flag-/Form-/Masken-/ Längenbedingungen. Kalte Broadcast-Zustände werden am tatsächlichen General-Copy-Punkt materialisiert; zusammenhängende Ein-Zeilen-Views werden nicht zusätzlich kopiert. Bestehende Bindungen und unveränderte Shader werden wiederverwendet; kein mathematisch ähnlicher Ersatzkernel. 130 Aufrufe der tatsächlichen MTPLX-Klasse prüfen Zeilen 1/2/4/6/7/32/2048, kalte/vorhandene Zustände, Masken, Fusionsflags und Längen unterhalb/in/oberhalb des gültigen Bereichs. Jeder Fall führt einen zweiten Forward auf beiden zurückgegebenen Zuständen aus. Verglichen werden finaler Hidden-Output, Conv-Zustand, FP32-Delta-Zustand sowie die erfassten Q/K/V-Zeilen. Alle 780 Hashes sind bitgenau; beim Export blieben die vorherigen 651 Receipts unverändert. Gemeinsamer Abschlusslauf: **16 Tests bestanden, 0 fehlgeschlagen, 0 ignoriert; 781 Fälle / 1.897 exakte Ausgabehashes**. Verbundene Ketten bleiben in einem Command Buffer. Quellcheck: 13 Custom-Körper / 33 Einträge, 17 Runtime-Einheiten / 81 Einträge. Beleg: `local-eval-results/20260906-mtplx-port/staged-gdn-combined-check.log`. **P06 bleibt offen.** Diese Operationen sind weiterhin `cfg(test)` und ersetzen noch nicht den produktiven FP32-Qwen-Graph. Separate GDN-Eingangsprojektionen, vollständige Advance-/Capture-Commit-Zustandsführung, No-Cache-/Batch-Hostpfade und gemeinsame Submission-/Concurrency-Semantik sind noch nicht vollständig angebunden. QSA/HC/PLE, Sampling/MTP und die zusammenhängende BF16-Produktmigration bleiben ebenfalls offen. Ausgabeidentität dieser Module ist weder eine Scheduling- noch eine UI-/Harness- oder Gesamtperformance-Abnahme. Kein Performance-Auswahlversuch, keine Rücknahme und kein Abschluss von P01–P16. ### Gemeinsame GDN-Projektion und tatsächliche Forward-Auswahl Die bisher doppelte Eingangsprojektion in gestuftem und fusioniertem Forward ist durch `gdn_project` ersetzt. `GdnInputWeights` bildet sowohl den fusionierten Pack als auch die vier separaten QKV-/Z-/B-/A-Module ab. Getrennte Module behalten ihre eigene Quantisierung und Aufrufreihenfolge; ihr zusammenhängendes Layout wird nicht wie ein fusioniertes View mit Zeilenstride 16480 behandelt. Die bestehenden Affine-/GPU-Bindungen werden wiederverwendet, keine Shaderänderung. `gdn_forward` übernimmt die Branch-Priorität für die installierte B=1-Geometrie: fusionierter Schritt nur bei entsprechendem Flag, lebendem FP32-Delta, einer unmaskierten Zeile, vorhandenem Cache, fehlenden Längen und inaktivem Verify-Capture. Ein fehlender Conv-Zustand bei vorhandenem Delta wird wie in der Referenz materialisiert. Ein vollständig kalter Aufruf startet gestuft; der Folgeschritt kann mit dem zurückgegebenen Delta in den fusionierten Pfad wechseln. Die Flags sind keine neu eingeführten Produktdefaults. 264 zusätzliche Aufrufe der tatsächlichen MTPLX-Klasse decken fusionierte, getrennte und gemischt Q4/Q8-quantisierte Eingänge mit Gruppen 32/64 ab; Zeilen 1/2/6/7/33/2048, kalte/vollständige/Conv-only/Delta-only-Zustände, Flags aus/an/ Step-only, Masken, Cache-Längen und Verify-Capture. Zwei aufeinanderfolgende Forwards behalten jeweils beide Zustände. Alle 792 Ausgabehashes und die tatsächlichen Step-/Conv-Branchentscheidungen sind exakt. Der Export prüfte außerdem alle bisherigen 781 Receipts unverändert. Gemeinsamer Prüflauf: **17 Tests bestanden, 0 fehlgeschlagen, 0 ignoriert; 1.045 Referenzfälle / 2.689 exakte Ausgabehashes**. Belege: `local-eval-results/20260906-mtplx-port/gdn-forward-check.log` und `gdn-forward-combined-check.log` (kompakter Sammelbeleg; dessen erste Tool-Ausgabe war gekürzt, der finale Teststatus ist vollständig). Quell-/Format-/Whitespace- Prüfungen bestanden. Keine Performanceauswahl oder Rücknahme. Die zuvor offene separate GDN-Eingangsprojektion ist damit auf Modulebene angebunden, **nicht im Produktgraph**. P06 bleibt für vollständige Advance-/ Capture-Commit-Zustandsführung, No-Cache-/Batch-Hostpfade und gemeinsame Submission-/Concurrency-Semantik offen. Das gesamte Modell bleibt auf dem alten Produktpfad; sämtliche übrigen Portierungs- und Gesamtperformancepflichten bleiben unverändert. Der bestehende Capture-Commit muss mit QSA-/PLE-Snapshots und gemeinsamer Validierung vor jeder Cache-Mutation portiert werden, nicht als isolierter GDN-Replay-Ersatz für den vollständigen Commit. ### QSA-Indexer-Vorbereitung und verbindliche restliche Pfadabdeckung Die tatsächliche QSA-Aufrufkette wurde in `qwen4_exp.py` von `QSACache` über `QSAIndexer` bis `Attention` verfolgt. Die folgenden Teile gehören gemeinsam zu P08; sie sind keine wahlweisen Performance-Optimierungen: | Abschnitt | Referenzverhalten / verbleibende Verpflichtung | | --- | --- | | Raw-/Pool-/KV-Zustand | Geometrisches Wachstum, reservierte Kapazitäten, logische Frontier, Trim/Restore; FP32-transponierter Pool-Mirror einschließlich Neuaufbau/Invalidierung | | Query-/Key-Vorbereitung | Quantisierte Projektion oder vorhandene QK-Zeilen, RMS/partielles RoPE, vollständige Key-Blöcke; fusionierte und Eager-Fallbackpfade | | Auswahl | Cache-Updates vor Dense==Sparse-Rückgabe; ursprünglicher Eager-Score/Top-k, Legacy-Fusion für Decode/kleine Verify-Fenster, gekachelter Prefill-Selektor und expliziter Compiled-State-Pfad | | Ergebnisformen | `blocks`, `prefill_blocks`, `row_tokens`, `dense_mask`, `update_only`; logische Grenzen und Scratch-/Kapazitätsbedingungen, kein stiller Retry nach Dispatchfehlern | | Attention-Verbraucher | Decode-Flash-Skip, Prefill-Flash, gekacheltes Prefill-Gather, Rows-Gather, Decode-Gather und Dense-SDPA; Masken/kausaler Tail/KV-Stride und Output-Gate erhalten | | Vision | M-RoPE und Dense-Causal-Verbrauch bei unverändert weiter gepflegtem QSA-Indexer-/Cache-Zustand | Umgesetzt ist jetzt die fusionierte **Indexer-Vorbereitung** mit den beiden unveränderten Körpern aus `qsa_indexer_prepare.py`: Query-RMSNorm/partielles RoPE und FP32-Blockmittelwert/BF16-Rundung/RMSNorm/RoPE für Keys. Der Exporter liest die Funktionsliterale als AST, schützt den Quelldateihash und löst nur Includes, Headerparameter und Einstiegspunkt-ABI auf. Stride-Metadaten behalten den ursprünglichen `constant int64_t`-Adressraum. Die Spezialisierung entspricht dem vorhandenen Modell: H4/D128/Rotary64/Ratio4/Epsilon1e-6/Attention-Scale1. Andere geometrische Konfigurationen sind dadurch nicht als portiert behauptet. `qsa_project_prepare` verbindet die bestehende quantisierte Affine-Operation mit dem ursprünglichen Query-Kernel; Raw-Key-Views behalten Zeilenstride 640. 105 zusätzliche Referenzfälle prüfen Query-Vorbereitung, Key-Pooling und die verbundene Projektion/Vorbereitung/Pooling-Kette: bis 2K Zeilen, 512 Key-Blöcke, strided und Stride-2-Views, große absolute Positionen, Q4g64/Q8g64/Q8g32. Die Frequenzen stammen unverändert vom tatsächlichen MTPLX-Modell. Alle 129 Hashes sind exakt; sämtliche vorherigen 1.045 Receipts blieben beim Export unverändert. Gemeinsamer Prüflauf: **18 Tests bestanden, 0 fehlgeschlagen, 0 ignoriert; 1.150 Referenzfälle / 2.818 exakte Ausgabehashes**. Vollständiger Beleg: `local-eval-results/20260906-mtplx-port/qsa-prepare-combined-check.log`. Quellcheck: 15 Custom-Körper / 35 Einträge plus 17 Runtime-Einheiten / 81 Einträge. Format- und Whitespace-Prüfungen bestanden. **P08 bleibt offen:** Der verbundene Vorbereitungstest ist nicht der vollständige Indexer mit Cache/Selektion und nicht der Attention-Forward. Die übrigen Tabellenabschnitte, Eager-Fallback und Produktintegration sind noch ausstehend. Der kanonische Rust-Pfad bleibt `cfg(test)`; weder UI-/Harness-Verhalten noch Gesamtlaufzeit oder das all-model ±2%-Ziel wurden hiermit abgenommen. ### QSA-Cache-Lebenszyklus einschließlich Session-State-Aliasing `QsaCache` verbindet Raw-Key-Schreibzugriffe, ursprüngliches Key-Pooling, geometrisches Indexer-Wachstum, KVCache-Schrittwachstum, Reservierung, Trim, State-Restore und den abgeleiteten FP32-Mirror. Strided KV-Slices werden am ursprünglichen Copy-Punkt materialisiert. Nur vorhandene Original-Copy-/Cast- und Pooling-Kernel werden verwendet. Die Speicherzählung entspricht `QSACache.nbytes`, einschließlich Backing-Kapazitäten und ohne FP32-Mirror. Der Referenztest hat eine falsche Annahme korrigiert: State-Leaves sind **nicht generell immutable**. Der Setter übernimmt die Python-Array-Objekte; `__setitem__` ersetzt deren Descriptor und ist über dieselben Objekt-Aliase sichtbar. Separate Slices teilen dagegen nur Storage. Rust bildet beide Ebenen getrennt mit lokalen `Rc` und `RefCell` ab; beim Wachstum wird wie in MTPLX ein neues Objekt gebunden. Dieser Unterschied wird durch erhaltene Snapshots nach Restore/Trim/Write geprüft, nicht durch angepasste Sollwerte verdeckt. 44 zusätzliche Zustandsübergänge mit 536 Ausgabehashes stimmen bitgenau überein: kalter und vorreservierter Cache, mehrere Kapazitätsgrenzen, drei gleichzeitig gehaltene Snapshots, Fortsetzung nach Restore, vollständiger Trim und erneuter Aufbau. Verglichen werden auch ungenutzte Buffer-Bereiche und der Mirror. Alle 1.194 Referenzfälle wurden erneut ausgeführt; vorherige Hashes unverändert. Gemeinsamer Prüflauf: **19 bestanden, 0 fehlgeschlagen, 0 ignoriert; 1.194 Fälle / 3.354 exakte Hashes**. Beleg: `local-eval-results/20260906-mtplx-port/qsa-cache-combined-check.log`. **P08 und Produktintegration bleiben offen.** Der Cache-Port bleibt zusammen mit den bisherigen kanonischen Operationen `cfg(test)`. Vollständige QSA-Selektion, Attention und Compiled-Indexer-State-Commit sind noch anzubinden. Dies schließt weder den Audit noch UI-/Harness- oder Gesamtperformance-Parität ab. ### Ursprüngliche QSA-Selektion und verbundene Cache-Ausführung `qsa_indexer_select.py` ist mit unverändertem gemeinsamen Header, Selektorkörper und allen drei Epilogen (`blocks`, `dense_mask`, `row_tokens`) übernommen. `metal/mtplx-qsa-select.json` enthält die AST-extrahierten Originalteile samt Quelldatei-/Teilhashes. Rust setzt die ursprünglichen Header-Literale für die jeweilige Backing-Kapazität ein; weder Laufzeitparameter statt Compile-Konstanten noch feste Testkapazitäten ersetzen die Referenzspezialisierung. Die bestehende native Pipeline-Bindung kompiliert diese Formen mit MTPLXs Safe-Math- und Metal-Sprachversionsauswahl und verwendet ihren vorhandenen Cache weiter. Die verbundene Host-Kette umfasst Raw-Key-Schreiben, ursprüngliches Pooling, Query-Vorbereitung, Selektion und KV-Fortschreibung. `_select_fused` begrenzt wie die Referenz den Score-Scratch pro Dispatch auf 32 MiB durch Query-Chunking, nicht History-Kürzung. Chunk-Ausgaben werden mit den ursprünglichen typisierten GeneralGeneral-Copies zusammengefügt; die dichte Maske bleibt ein logischer Slice der kapazitätsbreiten Ausgabe. Die allgemeine Metal-Bindung verwirft keine Byte-Offsets pauschal wegen einer nur für breitere Typen passenden Vierergrenze. 84 neue Referenzfälle / 168 Hashes sind exakt: BF16/FP32 und gemischte Operanden, TF32 an/aus, Strides, leere logische Historie, kausale Grenzen, Padding und All-zero-Ties; außerdem tatsächliches Host-Chunking bei 65.536 reservierten Blöcken sowie drei aufeinanderfolgende Cache-Forwards. Header und vollständiger Selektorkörper stimmen zusätzlich mit den tatsächlich erzeugten MTPLX-Quellen überein. Alle vorherigen 1.266 Receipts blieben beim erneuten Export unverändert. Gemeinsamer Prüflauf: **21 bestanden, 0 fehlgeschlagen, 0 ignoriert; 1.278 Fälle / 3.522 exakte Hashes**. Beleg: `local-eval-results/20260906-mtplx-port/qsa-select-combined-check.log`. **Offen bleiben** der große vektorisierte Prefill-Selektor, Eager- und Compiled- Indexerzweige, Attention-Verbraucher und die zusammenhängende Produktintegration. Der kanonische Pfad ist weiter `cfg(test)`. Insbesondere nutzt das ursprüngliche `concatenate_gpu` einen Concurrent-Bereich; Ressourcenabhängigkeiten, diese Concurrency und automatische Commit-Grenzen sind gemeinsam in P05 zu portieren. Die exakten Ergebnisse hier sind kein Scheduling- oder Gesamtperformance-Beleg; kein P01–P16 geschlossen und keine Optimierung per Mikrobenchmark verworfen. ### Ursprünglicher QSA-Prefill: beide Score-Produzenten, Top-k und Cache-Fortsetzung Die beiden Prefill-Stufen aus `qsa_indexer_prefill.py` sind verbunden portiert: der ursprüngliche H4/D128-TensorOps-Score-Kernel (16 Query-Zeilen × 32 Keys pro Threadgroup) und der separate adaptive Insertion-/Radix-Top-k-Körper. Header, Körper und Epiloge bleiben unverändert; `mtplx-qsa-select.json` enthält zusätzlich die gepinnten Prefill-Quellen. Die vorhandene Pipeline-Kompilierung und typisierte Ausgabe-Verkettung werden gemeinsam mit dem Legacy-Selektor benutzt. MPP lädt über die ursprünglichen Strides ohne versteckte Contiguous-Copy. Der Top-k-Wrapper materialisiert dagegen nichtkontiguierliche FP32-Score-Views am ursprünglichen General-Copy-Punkt. Beide Fälle sind gegen echte Referenzaufrufe geprüft. Die producerabhängige 128-MiB-Planung samt Alignment-Abrundung ist übernommen: eine Score-Ebene für MPP, H4+1 für den allgemeinen FP32-Produzenten. Eine irreduzible Zeile darf wie in MTPLX das Budget überschreiten. Ein ausgewählter MPP-Kernel fällt bei Fehlern nicht auf einen anderen Pfad zurück. Die gemeinsame Rust-Funktion `qsa_prefill` enthält jetzt auch MTPLXs allgemeinen FP32-Score-Zweig: Cast, Matmul, ReLU pro Kopf, Kopf-Summe und Skalierung. Die Rust-Dispatch-Auswahl übernimmt `matmul.cpp` der gepinnten Runtime für H4/D128 auf M5 Max einschließlich GEMV, regulärem Steel/NAX und beiden Split-K-Varianten. Alle Shader stammen unverändert aus der gepinnten metallib. Vector-Casts erhalten transponierte/gebroadcastete Speicherlayouts; General-Casts materialisieren Views. Matmul prüft Transposition und bereits gebroadcastete Operanden vor der Batch-Zusammenfassung. Der Pool-Cast wird einmal über alle Chunks gehalten; Top-k und typisierte Verkettung sind für beide Produzenten gemeinsam. 384 neue Score-Fälle decken BF16/FP32-Queries, acht Layoutkombinationen, bis 2K Query-Zeilen und den echten `MLX_ENABLE_TF32=0/1`-Runtime-Schalter in separaten Prozessen ab. 160 der 192 Form-/Typ-Paare haben tatsächlich unterschiedliche TF32-an/aus-Referenzergebnisse; beide Varianten sind jeweils bitgenau. Dazu kommen 96 verbundene Prefill-Fälle mit allen vier BF16/FP32-Operandenpaaren, allen drei Ausgabeformen und erzwungenem Chunking einschließlich Alignment-Abrundung. `qsa_prefill_cached` verarbeitet den gültigen Pool-Ausschnitt wie der große MTPLX-Prefill-Zweig, nicht die reservierte Kapazität des Legacy-Selektors. Der fortlaufende Cache-Test hängt nach 1/4/7 Zeilen einen vollständigen 2K-Prefill an; Query-Vorbereitung, Raw-Writes, Pooling, Selektion und KV-Fortschreibung bleiben verbunden. Alle drei Selektions-Ausgabeformen sind geprüft. 159 neue Fälle / 284 Hashes: Kachelränder, bis 2K Query-Zeilen, bis 65.536 Key-Blöcke, Stride-2-/gepaddingte Score-Views auch mit nichtkonstanten Werten, kausale Grenzen, Null-/Einser-Ties, kurze/lange Radix-Kandidatenlisten, erzwungene Chunk-/Concat-Grenzen und reale Cache-Fortsetzung. Die vorherigen Receipts blieben bei den erneuten Referenzexporten unverändert. Gemeinsamer Prüflauf einschließlich der 480 zusätzlichen FP32-/Producer-Fälle: **25 bestanden, 0 fehlgeschlagen, 0 ignoriert; 1.917 Fälle / 4.382 exakte Hashes**. Beleg: `local-eval-results/20260906-mtplx-port/qsa-f32-prefill-combined-check.log`. **Nicht abgeschlossen:** vollständiger Eager-Indexer, Compiled-State/Graph-Bank, Attention-Verbraucher, vollständige Branch-Auswahl, Scheduling und Produktintegration. Die unterstützte M5-Prefill-Kette wird nicht als Ersatz für diese Zweige ausgegeben. Der kanonische Port bleibt `cfg(test)`; keine Änderung der UI-Performance behauptet, kein P01–P16 geschlossen und kein Gesamtbenchmark oder Rücknahmeentscheid vor der vollständigen Integration. ### Eager-Indexer: Selektion, Kachel-Eval und sämtliche Ausgabeformen Der kanonische Rust-Port enthält jetzt auch die untiled `_select_eager`-Kette: kausale Blockgültigkeit, FP32-Matmul/ReLU/Kopf-Summe/Skalierung, `where`, `block_id * 1e-12`-Tie-Break und die originale Runtime-`ArgPartition`-Ausführung (vollständiger Argsort). Die letzte K-Spalten-View behält den ursprünglichen Zeilenstride. Für `flash_prefill` folgen originale Int32-Sortierung, Int64-Indexkonvertierung, Bool-GatherAxis und Nullsetzen ungültiger Slots. Dense-Maske, Rows-Gather sowie beide Decode-Ausgaben (Flash-Blöcke und Gather-Tokenliste) sind ebenfalls verbunden. Dense verwendet den originalen Bool-ScatterAxis, Gültigkeit, Repeat/Concat und die Tail-/Kausalmaske. Rows-Gather behält die Argsort-Reihenfolge, liefert K*4+4 gepaddingte Tokens mit Gültigkeit und setzt ungültige IDs auf null. Decode sortiert chronologisch und hält die Tail-Grenze auf dem Host; Flash hat wie in MTPLX Vorrang vor Gather. Die für diese beiden lazy Ausgaben tote Dense-Maskenexpression wird nicht ausgeführt. GatherAxis/ScatterAxis verwenden unveränderte Originalkörper mit den benötigten Templatespezialisierungen; kein Ersatzkernel. Cast, Sort und Vektor-Dispatch werden zwischen den Epilogen geteilt. Die Referenzreceipts stammen aus tatsächlichen `QSAIndexer._select_eager`- Aufrufen. Beobachter reichen `where`/`argpartition` unverändert weiter und lesen die realen Zwischenwerte; die Blockausgabe wird über den echten Prefill-Phasen- und Konfigurationspfad ausgewählt. 60 Zwischenwert- und 24 verbundene Blockfälle prüfen BF16/FP32, Null-Ties, kausale Grenzen, bis 2K Queries und bis 65.536 Blöcke, jeweils mit dem echten TF32-Runtime-Schalter an/aus. Hinzu kommen 144 Dense-, 108 Rows-Gather- und 72 Decode-Fälle, einschließlich Tail-Längen 0/1/3 und gleichzeitig gesetzten Flash-/Decode-Gather-Schaltern. Insgesamt prüfen 408 Eager-Fälle die echten MTPLX-Ausgaben bzw. Zwischenwerte. `_tiled_topk` ist an dieselbe Score-/Ranking-Kette angeschlossen. Block-/Tie- Vektoren und der FP32-Pool werden geteilt. Jede Kachel wartet synchron auf das Top-k-Ergebnis, bevor die nächste entsteht; kein Ersatz durch asynchrones Flush. Score-Scratch wird nach der Kachel freigegeben, die ausgewerteten ArgPartition- Views bleiben bis zum originalen GeneralGeneral-Concat erhalten. Der Indexstride wechselt dabei von N auf K; Gültigkeit behält ihren N-Stride. Alle Epiloge beachten beide Strides. Der ganze Blockgültigkeitsausdruck folgt erst nach den Kachel-Evals. `qsa_eager_output` entscheidet die Rückgabe nun gemeinsam in Referenzreihenfolge: Prefill-Blöcke, Decode-Flash, Decode-Gather, ungekächeltes Rows-Gather, Dense. Die gemeinsame Large-Prefill-Berechtigung ist weiterhin ein Eingabeparameter; ihre vollständige Verknüpfung mit Indexer/Compiled-Core gehört zur offenen Indexer-Integration. Die neuen Tests wählen nicht selbst den erwarteten Epilog, sondern übergeben dieselben Schalter wie der MTPLX-Aufruf. Insbesondere bleibt Gather eingeschaltet, wenn der gekachelte Zweig trotzdem Dense zurückgeben muss. 132 zusätzliche Fälle / 198 Hashes prüfen echte Kachel-Eval-Aufrufe, 2K Queries, 65.536 Blöcke, Stride-2-FP32-Queries, Tail 0/1, Kachelreste und die Abschaltung der Kachelung bei Kachelgröße >= Query-Zeilen. 108 Fälle sind tatsächlich gekachelt; 24 prüfen diese Abschaltgrenze. Die Referenzreceipts erfassen die unverändert weitergereichten `mx.eval`-Aufrufe. Das beweist nicht die allgemeine Graph-Tape-/Allocator-/Concurrency-Parität innerhalb einer Eval-Grenze. Gemeinsamer Korrektheitslauf: **26 bestanden, 0 fehlgeschlagen, 0 ignoriert; 2.457 Fälle / 5.240 Hashes**, davon 540 Eager-Fälle. Quellenexport, Formatierung und Diff-Whitespace-Prüfung bestanden. Erneute Originalexporte bestätigen alle 1.947 Default-/TF32-an- und 510 TF32-aus-Receipts unverändert. Beleg: `local-eval-results/20260906-mtplx-port/qsa-eager-tiled-combined-check.log`. ### Eager-Vorbereitung im Projektions- und Cache-Pfad Die Eager-Query-/Pool-Vorbereitung ist für die installierte BF16-Geometrie (Q H4/D128, Pool H1/D128, Rotary64, Ratio4, Epsilon1e-6, Skalierung1) verbunden. Nichtkontiguierliche Projektionsslices werden vor RMSNorm mit der originalen General-Copy materialisiert. Pooling bleibt FP32-Summe mal 0,25 mit anschließendem BF16-Cast vor RMSNorm. RoPE verwendet die ursprünglichen Arange-/Cast-/Concat-, Cos/Sin-, BF16-Negative- und FP32-Multiply/Add-Schritte samt abschließendem BF16-Cast und unverändertem Pass-through-Anteil. Kein Ersatz durch den fusionierten Kernel; keine neuen Shaderkörper. General-Copy und die vorhandenen Norm-/Cast-/ Concat-Dispatcher werden gemeinsam genutzt. `qsa_project_prepare` und `QsaCache::extend_pooled` besitzen jetzt beide Vorbereitungszweige. Ihre Zwischenpuffer werden durch die verbundenen Operationen bis zur Auswertung gehalten. 105 neue Originalfälle prüfen Query-, Pool- und quantisierte Projektionsketten, einschließlich Padding/Stride2, hoher Positionen und 2K-Zeilen. 44 zusätzliche echte QSACache-/KVCache-Übergänge prüfen Eager- Pooling bei Wachstum, Reservierung, Trim, Snapshots/Restore und Spiegel-Neuaufbau. Die bisherigen 2.052 Default-/TF32-an-Fälle blieben beim letzten vollständigen Originalexport unverändert; hinzu kamen die 44 Eager-Cache-Fälle. Der Eager-Selektions-Test prüft nun auch die tatsächliche Anzahl abgeschlossener Command Buffer über die vorhandenen `GpuBusyStats`: genau ein Abschluss je beobachtetem MTPLX-Kachel-Eval plus ein finaler Ausgabe-Batch. Dies ersetzt nicht den weiterhin offenen Nachweis der allgemeinen Graph-/Scheduling-Parität. Gemeinsamer Korrektheitslauf: **26 bestanden, 0 fehlgeschlagen, 0 ignoriert; 2.606 Fälle / 5.905 Hashes**, davon 210 Vorbereitungsfälle und 88 Cache-Übergänge. Quellenexport, Formatierung und Diff-Whitespace-Prüfung bestanden. Beleg: `local-eval-results/20260906-mtplx-port/qsa-eager-preparation-combined-check.log`. ### Verbundener nicht-kompilierter Indexer-Aufruf `qsa_indexer_rows_uncompiled` bildet den Abschnitt von `_call_rows` nach der Compiled-Entscheidung zusammenhängend ab: eigene quantisierte Projektion oder mitgelieferte Q/K-Zeilen, Query-Vorbereitung, Raw-Write, Pool-Fortschreibung und Selektion. Die bestehenden Ketten werden wiederverwendet. Im Dense==Sparse- Bereich bleibt die ungenutzte Query-Vorbereitung wie in MTPLXs Lazy-Ausführung unausgewertet. Der KV-Offset wird erst vom nachfolgenden Attention-Schritt erhöht, nicht vor der Indexer-Selektion. Die Zweigauswahl berücksichtigt Phase, früheste Query-Position, Prefill-Mindest- breite, Gather-Schwellen und Decode-Gather-Ausschluss des Legacy-Fused-Zweigs. Large-Prefill verwendet die logische Pool-Sicht, Legacy-Fused die reservierte Backing-Kapazität; Eager verwendet den gespeicherten FP32-Spiegel. Die Rückgabe beschränkt sich auf die vom Modell konsumierten Ausgaben und hält die übrigen Kernel-Ausgabepuffer bis zur Auswertung. Der gemeinsame Rückgabetyp heißt deshalb jetzt `QsaIndexerSelection`, nicht mehr `QsaEagerSelection`. 92 Originalaufrufe in 24 fortlaufenden Sequenzen prüfen kalten Start, den Budgetübergang, projizierte und mitgelieferte Q/K-Zeilen (704er Zeilenstride), 2K-Zeilen, 32K-Historie, Flash/Gather-Vorrang, aktivierte Kachelung und die Prefill-Schwelle auf beiden Seiten. Die Fixtures rufen den echten MTPLX-Indexer auf; Beobachter reichen seine Selektionsmethoden unverändert weiter. Rust prüft den tatsächlich gewählten Pfad, 82 Selektionshashes, 268 zusätzliche Raw-/Pool-/ Spiegelhashes, Kapazitäten/Offset und abgeschlossene Command Buffer. Die numerische Prüfung wertet Cache-Zustände explizit aus; sie ist kein Beleg für den vollständigen Lazy-Graph-Lebenszyklus einer Modellgenerierung. Gemeinsamer Korrektheitslauf: **27 bestanden, 0 fehlgeschlagen, 0 ignoriert; 2.698 Fälle / 5.987 Ausgabehashes plus 268 Zustands-Hashes**. Quellenexport, Formatierung und Diff-Whitespace-Prüfung bestanden. Der erneute Originalexport bestätigt alle 2.188 Default-/TF32-an-Fälle unverändert, einschließlich der Indexer-Sequenzen und Zustands-Hashes. Beleg: `local-eval-results/20260906-mtplx-port/qsa-indexer-routes-combined-check.log`. **Weiter offen:** Compiled-Eignungsentscheidung und Compiled-State/Graph-Bank, Attention, Scheduling und Produktintegration. Insbesondere ist die breiteabhängige BFS-Tape-Planung aus Runtime `transforms.cpp` nicht durch serielles Rust-Encoding nachgewiesen. Der explizit nicht-kompilierte Einstieg ersetzt keinen geeigneten Compiled-Pfad. P05 und P08 bleiben offen; keine Gesamtmodell-/Performance-Parität behauptet. Compiled-Cache-Voraussetzungen sind anschließend gegen die Referenz geprüft: `qsa_replay_capacity` übernimmt die Power-of-two-Buckets einschließlich des festen `ceil(S/4)`-Stagingfensters; `ensure_compiled_backings` berücksichtigt ausstehende Reservierungen und materialisiert unberührte Backings. 108 reine Kapazitätsfälle und vier echte `_ensure_compiled_backings`-Übergänge prüfen unter anderem S=1025 und die Übernahme vorhandener Daten, ohne KV-Offset oder logische Pool-Länge vorzeitig zu verändern. Acht weitere Fälle prüfen die originalen dynamischen BF16-Kopien mit int32-GPU-Startwerten, 128/704-Stride und bis zu 2048 Zeilen. Keine Host-Auslese der Startwerte. Die gemeinsame Kopierfunktion nutzt dieselben bisherigen Kernel/Geometrien für statische Aufrufe; nur dynamische Aufrufe binden die originalen int64-Offset-Leaves. `tools/mtplx-jit-reference.py --operation qsa-update --check` führt den echten Compiled-Indexer aus und prüft drei unveränderte erfasste Shader: Fused Clamp, Multiply und Dynamic Offset. Alle drei sind jetzt im verbundenen `qsa_compiled_cache_window` verwendet: Raw-Update, dynamische Clamp-Grenze, festes Raw-Fenster, originales Pooling und Pool-Update. Der unveränderte Runtime-Header ist ebenfalls übernommen. Die drei originalen Constant-CSE- Layouts (obere Grenze null / gleich max_new / verschiedene Konstanten) sind separat erfasst; Rust spezialisiert nur Formkonstanten und exportierte Symbole. Eine zusätzliche Originalvariante mit 257/255 prüft diese Spezialisierung. 26 echte `QSACompiledIndexerCore.select_qk_rows`-Aufrufe prüfen die komplette Cache-Ausgabe und unveränderte Eingangs-Backings: 104 zusätzliche Hashes, 640/704-Zeilenstride, unvollständige Blöcke, rückwärts verschobenes Poolfenster, Kapazitätsgrenzen und S=2048. Startwerte bleiben GPU-Leaves; kein Zwischen-Eval oder Frontier-Readback. Die Referenz hält Eingangs-Leaves während der Auswertung fest. Damit ist ausdrücklich der **nicht-donierende Kopierzweig** geprüft, nicht der Allokator oder das vollständige Graph-Replay. Eignungsentscheidung, Graph-Bank, Donation, BFS-Tape, Modell-Aufrufintegration und Produktionsintegration bleiben offen. Keine Modell-/Performance-Parität. Neue Referenzfälle: `tests/fixtures/mtplx-qsa-compiled-state.jsonl`; gemeinsamer Lauf: `local-eval-results/20260906-mtplx-port/qsa-compiled-state-check.log`. Dieser frühere Voraussetzungslauf besteht mit **29 Tests, 0 fehlgeschlagen, 0 ignoriert** und deckt insgesamt **2.818 Fälle / 6.019 Ausgabehashes plus 268 Zustands-Hashes** ab. Quellenexport, frische JIT-Referenzprüfung, Formatierung und Diff-Prüfung bestehen. Der anschließende verbundene Cache-Fenster-Lauf besteht mit **31 Tests, 0 fehlgeschlagen, 0 ignoriert**: **2.844 Fälle / 6.123 Ausgabehashes plus 268 Zustands-Hashes**. Alle vier Compiled-Quellenproben einschließlich des unveränderten Runtime-Headers sind frisch reproduziert. Neue Fälle: `tests/fixtures/mtplx-qsa-compiled-window.jsonl`; vollständiger Beleg: `local-eval-results/20260906-mtplx-port/qsa-compiled-window-check.log`. Der verbundene BF16-Q/K-Einstieg umfasst jetzt alle fünf festen Ausgabemodi (`update_only`, `blocks`, `row_tokens`, `dense_mask`, `prefill_blocks`). Die Query-Vorbereitung sowie Legacy-/Prefill-Top-k binden echte int32-GPU-Leaves; bestehende Host-Aufrufe verwenden dieselben Dispatch-Funktionen. Die originale kompilierte Positionsaddition wird auch für `+0` ausgeführt. Vier unverändert erfasste Add-Kernel prüfen die reine Formkonstanten-Spezialisierung. Die Selektionskachelung verwendet die gesamte Pool-Kapazität, das jeweilige Scratch-/Workspace-Budget und die originale Prefill-Abrundung auf 32 Zeilen. 66 echte `QSACompiledIndexerCore.select_qk_rows`-Aufrufe vergleichen sämtliche Selektionsausgänge und unveränderte/aktualisierte Cache-Backings: 144 zusätzliche Ausgabehashes und 264 Zustands-Hashes. Darunter sind gekachelte Legacy-Ausgaben, Prefill mit 2048 Zeilen, 640/704-Stride und die reine Update-Route. Rust bestätigt jeweils einen abgeschlossenen Command Buffer ohne Zwischen-Eval. Das beweist die verbundene Q/K-Arithmetik im Retained-Input-Zweig, **nicht** das noch offene Graph-Replay oder identische BFS-Reihenfolge. Neue Fälle: `tests/fixtures/mtplx-qsa-compiled-indexer.jsonl`; Beleg: `local-eval-results/20260906-mtplx-port/qsa-compiled-indexer-check.log`. Gemeinsamer Lauf: **32 Tests bestanden, 0 fehlgeschlagen, 0 ignoriert**; **2.910 Fälle / 6.267 Ausgabehashes plus 532 Zustands-Hashes**. Originalquellen, frische Compiled-Add-/Update-Proben, Formatierung und Diff-Prüfung bestanden. Der Hidden-Einstieg ist anschließend an denselben Q/K-Pfad angeschlossen: `qsa_compiled_indexer_hidden_retained` führt die originale affine Quantisierung vor Cache-Aktualisierung und Selektion im selben asynchronen Aufruf aus. Es gibt keinen Zwischen-Eval oder abweichenden Selektionspfad. 132 echte `QSACompiledIndexerCore.select_hidden`-Aufrufe prüfen 4-/8-Bit-Projektionen mit Gruppengröße 32/64, alle fünf Modi und dieselben Kachel-/2K-Prefill-Grenzen: 288 weitere Ausgabehashes und 528 Zustands-Hashes. Die ursprünglichen 66 Q/K-Referenzfälle sind frisch unverändert reproduziert. Zusammen prüft der verbundene Test 198 Aufrufe. Dies schließt die arithmetische Projektion ein, nicht die offene Eignungsentscheidung, Graph-Bank, Donation/BFS oder den produktiven Modell-Aufruf. Neue Fälle: `tests/fixtures/mtplx-qsa-compiled-hidden.jsonl`; Beleg: `local-eval-results/20260906-mtplx-port/qsa-compiled-hidden-check.log`. Gemeinsamer Lauf: **32 Tests bestanden, 0 fehlgeschlagen, 0 ignoriert**; **3.042 Fälle / 6.555 Ausgabehashes plus 1.060 Zustands-Hashes**. Formatierung, Originalquellenexport und Diff-Prüfung bestanden. Keine neuen Metal-Kernel, Modelldownloads oder Produktions-/Performance-Abnahme in diesem Schritt. Die Host-Routenauswahl ist jetzt für den installierten B1/BF16/Ratio4-Vertrag mit Cache-Commit und Ausgabeadapter verbunden (heute `qsa_indexer_rows`). `QsaIndexerOptions` übernimmt Compiled-Schalter und kanonische Compile-Breite; Prefill-Eignung verwendet den frühesten Query und den echten Phasenwert. Die Eignungsprüfung läuft vor Kapazitäts-Bucketing, berücksichtigt fehlende Backings, Cache-Lücken und Flash-Vorrang gegenüber Decode-Gather. 720 Aufrufe der unveränderten MTPLX-Hostmethoden (12 Optionssätze × 30 Cache-Zustände × Hidden/QK) stimmen überein, einschließlich nicht-potenzförmiger Kapazitäten. Das ist die Cache-/Phasenentscheidung für feste Modelldatentypen, kein Nachweis beliebiger Source-/Norm-/Projektions-Datentyp- und Shape-Eignung. 108 zusätzliche vollständige Original-Indexer-Aufrufe in 28 fortgesetzten Sequenzen prüfen die Verbindung von Eignung, Backing-Reservierung, GPU-Frontiers, Rechenpfad und Host-Commit: 38 Compiled-Aufrufe sowie tatsächliche Eager-, Prefill- und Update-only-Alternativen. Cache-Raw/Pool und logischer Frontier werden ohne Readback ersetzt; ein früherer FP32-Mirror wird invalidiert; KV.offset bleibt bis zur anschließenden Attention-KV-Aktualisierung unverändert. Flash-/Prefill-/Gather-Ausgaben und der logische Ausschnitt der kapazitätsbreiten Dense-Maske stimmen mit dem Original überein. Dispatched Fehler werden nicht durch einen Eager-Fallback verborgen. Die 92 bisherigen Aufrufe verwenden jetzt denselben verbundenen Rust-Einstieg mit abgeschaltetem Compiled-Schalter; der gemeinsame Test prüft 200 Aufrufe einschließlich echter Command-Buffer-Zahl. Neue Referenzen: `tests/fixtures/mtplx-qsa-compiled-routes.json` und `tests/fixtures/mtplx-qsa-indexer-connected.jsonl` (98 Ausgabe-/282 Zustands-Hashes). Gemeinsamer Lauf: **33 Tests bestanden, 0 fehlgeschlagen, 0 ignoriert**; **3.150 Rechenfälle / 6.653 Ausgabehashes plus 1.342 Zustands-Hashes**, zusätzlich 720 Host-Routingentscheidungen. Beleg: `local-eval-results/20260906-mtplx-port/qsa-connected-routing-check.log`. Originalkernel unverändert. Weiterhin ausdrücklich offen: Graph-Bank und Parameteridentität, Donation/BFS/Allocator, vollständige Modell-/Produktintegration und danach die Gesamt-Performanceabnahme. Der verbundene Testpfad verwendet noch die ausdrücklich benannte Retained-Input-Ausführung; er ist kein Ersatz für die fehlende Runtime-Parität und bleibt außerhalb des Produktpfads. Die direkte Compiled-Rechenkette ist danach durch eine echte QSA-Graph-Bank ersetzt worden (`src/engine/metal/qwen_mtplx/qsa_graph.rs`). Ein struktureller Schlüssel erzeugt einmal die Primitiv-Knoten und ihren Ausführungsplan; Wiederaufrufe binden die zehn aktuellen Array-Eingaben. Frontier-Werte und Q/K-Strides sind keine Trace-Schlüssel. Query-/Key-Views, dynamische Updates, ursprüngliche skalare Compiled-Operationen, Pool-/Query-Vorbereitung, MPP-/Topk- oder Legacy-Selektion und jede einzelne Concatenate-Ausgabe bilden explizite Abhängigkeiten. Die bisherigen direkten Compiled-Hidden-/QK-/Selektionsketten sind entfernt, nicht als zweite Ausführung daneben behalten. 99 vor dem Eval exportierte optimierte MTPLX-Graphen prüfen Primitiv-Abhängigkeiten und Mehrfach-Ausgaben für alle Modi, Kachelgrenzen und beide Einstiege. Evaluierte Konstanten werden im Struktur-Fingerprint ausgespart; Originalshader und numerische Ergebnisse bleiben separate Prüfungen. Die 2K-Constant-CSE-Variante ist enthalten. Der Plan verwendet den Degree-/BFS-Algorithmus des gepinnten `mlx/transforms.cpp:180` mit Breitenlimit 20, spezialisiert auf einen Stream und bereits evaluierte Eingaben. Dies ist noch **kein** globaler Modellgraph oder Nachweis der tatsächlich überlappenden Metal-Encoder-Zeitlinie. Alle 198 bisherigen Compiled-Rechenfälle laufen jetzt durch diese Graph-Bank; ein Q/K-Layoutwechsel 640→704 muss denselben Graphen wiederverwenden. Die 108 fortgesetzten Original-Indexer-Aufrufe wurden frisch um echte `compiled_calls`-/`traces`-/Entry-Zähler ergänzt; sämtliche bisherigen Inhalte und Hashes blieben unverändert. Rust stimmt auch mit diesen Zählern überein, einschließlich vier Wiederaufrufen ohne neue Trace. Parameterersetzung verwirft die Bank; ein zusätzlicher Austausch-/Rücktausch-Test prüft Invalidierung und erneuten Layout-Replay. Die noch testgebundene Buffer-Identität verhindert dabei Verwechslungen durch wiederverwendete native Adressen, ohne den gegenwärtigen Produkt-Buffer um Laufzeitaufwand zu erweitern. Gemeinsamer Lauf **33/33 bestanden**, danach der ergänzte Identitäts-Test bestanden. Die bestehende Rechenfall-/Hash-Zahl bleibt unverändert; neu sind 99 Graphstruktur-Referenzen in `tests/fixtures/mtplx-qsa-compiled-graphs.jsonl` und die Engagement-Zähler im verbundenen Fixture. Originalquellenexport, Formatierung, Diff-Prüfung und `cargo check --release --bin ds4-server` für die Nicht-Test-Konfiguration bestanden. Beleg: `local-eval-results/20260906-mtplx-port/qsa-graph-replay-check.log`. Weiter offen sind insbesondere Donation, frühzeitige Freigabe/Allocator, modellweiter lazy Graph mit passender Root-/Stream-/Encoder-Ausführung, generische Tensor-Eignung und die Produktintegration. Intermediates bleiben in dieser Retained-Lane noch bis zum Aufrufende gehalten. P05/P16 und das vollständige 2%-Ziel bleiben offen; keine Performance-Abnahme aus diesen Tests. Die Lebensdauer der Graph-Zwischenwerte folgt nun dem letzten Verbraucher: Der gecachte Plan enthält die Freigabestellen, einschließlich aller Geschwister einer Mehrfach-Ausgabe. Nach einem Primitiv werden nicht mehr benötigte Graph-Referenzen gelöst; nur die echten Ergebnisblätter bleiben im Resultat. Block-/Raw-Start-Scratch gehört nicht mehr zum Graph-Ergebnis. Die GPU-seitige Freigabe ist davon getrennt: Rust überträgt besessene Puffer an einen Completion-Handler des bereits offenen Command Buffers. Es wird weder ein zusätzlicher Command Buffer angelegt noch ein Flush oder Wait ausgelöst. Leere Batches nehmen keinen Besitz an; ohne offene/ausstehende Arbeit erfolgt die Freigabe unmittelbar. Ein eigener Test prüft diese Besitzübergabe vor und nach einem asynchronen Flush. Die 198 Rechenfälle prüfen zusätzlich, dass am Aufrufende nur Ergebnisblätter übrig sind und keine ausgemusterten Graph-Blätter als versteckte Temporaries zurückgegeben werden. Die gezählten Graph-Blätter sind ausdrücklich **keine** Messung physisch bereits freigegebenen GPU-Speichers. Der verschärfte Lauf mit `DS4_METAL_UNRETAINED_COMMAND_BUFFERS=1` deckte vier `Invalid Resource`-Fehler auf (Cache-Lifecycle, Compiled-Indexer, verbundene Cache-Selektion und Indexer-Routing). Ursache: Die gemeinsame kanonische Metal-Dispatch-Grenze hielt gebundenen Speicher nicht selbst bis zum GPU-Ende; ein kurzlebiges Argument konnte vor Batch-Commit verschwinden. Das war durch Metals Standard-Retention verdeckt. Korrigiert ist die gemeinsame Dispatch- Grenze, nicht jeder betroffene Aufrufer: gebundene Metal-Ressourcen werden dedupliziert bis zum Completion-Callback gehalten und dort explizit freigegeben. Das entspricht dem Lifetime-Vertrag des gepinnten GPU-Evaluators; die native Bridge hält nur Plattform-Ressourcen, Modell-/Graph-Orchestrierung bleibt Rust. Compile und Dispatch haben zudem eigene Autorelease-Pools wie das Original `gpu::eval`, damit Foundation-Temporaries nicht am Lebensende des Worker-Threads hängen. Keine Kernelquelle, Dispatch-Geometrie oder Host-/GPU-Synchronisation wurde dadurch geändert. Der normale vollständige Lauf besteht mit **34/34 Tests**; der verschärfte Lauf nach der gemeinsamen Ressourcen-Korrektur ebenfalls. Rechen-/Graph-Fixtures bleiben unverändert. Rohfehler und erfolgreiche Verifikation werden in `local-eval-results/20260906-mtplx-port/qsa-lifetime-check.log` getrennt bewahrt. Aktuelle vollständige Sammlung ist nun `cargo test --release qwen_mtplx -- --include-ignored --test-threads=1`, damit der neue Lifetime-Test im Graph-Modul nicht durch den alten engeren Filter ausgelassen wird. Donation verlangt nach MTPLX exklusiven Array-Descriptor **und** exklusiven Data-Besitz, passende Elementgröße und höchstens 16 KiB Überhang. Dabei zählen auch die noch ausstehenden GPU-Evaluator-Referenzen. Weder der letzte Graph-Verbraucher noch ein einzelner `Rc::strong_count` beweist diese Bedingungen. Ebenso offen: vollständiger Allocator, modellweiter lazy Graph, Root-/Stream-/Encoder-Parität und Produktintegration. Keine UI-Stall-Behebung oder Performance-Parität wird aus diesem noch testgebundenen Port abgeleitet. ### Getrennter Array-/Data-Besitz im kanonischen Port Die gemeinsame testgebundene `Buffer`-Schicht unterscheidet jetzt eine eindeutige Array-/View-Identität vom gemeinsam referenzierten Data-Besitz. Auch verschachtelte native Views teilen denselben Rust-Data-Besitz; der native Root wird erst mit dem letzten Data-Besitzer freigegeben. Der GPU-Completion-Transfer hält Data, nicht mehr ausgemusterte Graph-/View-Descriptoren. Die Data-Referenz bleibt dadurch nach Graph-Detach sichtbar. `Buffer` selbst bleibt nicht `Send`/`Sync`; nur der private, nicht zugängliche Allocation-Besitz darf abschließend vom Completion-Thread über die bereits mutex-geschützte native Freigabe zerstört werden. Damit ist eine konkrete COW-Lücke an der gemeinsamen `QsaArray.shared_storage`- Grenze geschlossen: bisher wurden nur mehrere `Rc` erkannt, nicht zwei verschiedene Buffer-Views derselben Allocation. Der direkte gepinnte MTPLX-Test (`QSACache.write_raw`, Runtime 0.32.2, modellfrei) bestätigt für ein Update 1→2: Ein Alias desselben Array-Objekts sieht 2, eine vorher ausgewertete View bleibt 1. Der entsprechende Rust-Test wurde negativ geprüft: Nur die alte Besitzprüfung wiederhergestellt ergibt einen Fehlschlag (View fälschlich 2); die Korrektur erhält 1. Die bestehende Sammlung und ihre numerischen Fixtures bleiben erhalten. Der Completion-Test prüft zusätzlich verschachtelte Views, Root-Lebensdauer und sichtbaren GPU-Data-Besitz vor/nach Abschluss. Belege: `local-eval-results/20260906-mtplx-port/qsa-data-ownership-check.log`. Normaler und verschärfter Lauf bestehen mit jeweils 34/34 Tests; Kernelquellen- Prüfung, produktiver Release-Buildcheck, Formatierung und Release-Test-Clippy bestehen ebenfalls. Die Abhängigkeit `block 0.1.6` meldet weiterhin nur ihren bekannten Future-Incompatibility-Hinweis. Die QSA-Graphauswertung registriert inzwischen nach jedem Primitiv dessen Eingaben (einschließlich gebundener Projektionsparameter) und Geschwisterausgaben als deduplizierte Data-Menge, abzüglich der tatsächlich ausgewerteten Hauptausgabe, wie im gepinnten `backend/metal/eval.cpp`. Die Halterung beginnt vor dem nächsten Primitiv, nicht erst beim letzten Graph-Verbraucher. Graph-Detach löst nun nur die Descriptoren; ein zweites Halten dieser Blätter würde die Hauptausnahme wieder aufheben. Backend-Scratch und Fehlerpfad behalten ihre eigene Halterung. Der Scheduler führt dafür neben dem Produzenten diejenige Geschwisterausgabe mit, deren geteilte Abhängigkeitszahl null wurde; sie ist nicht immer Ausgabe null. Ein CPU-Test deckt unterschiedliche Root-Reihenfolgen und doppelte Kanten ab. Ein Metal-Test prüft leere Batch-Fallbacks, deduplizierte Views, Hauptausgabe eins, die Ausnahme bei geteiltem Eingabe-/Ausgabespeicher und Referenzzahlen vor/nach GPU-Abschluss. Es gibt keinen neuen Flush, Wait, Kernel oder GPU-Readback. Belege: `local-eval-results/20260906-mtplx-port/qsa-evaluator-holds-check.log`. Die erweiterte Sammlung besteht normal und mit unretained Command Buffers jeweils mit **36/36 Tests**. Kernelquellen-Prüfung, Release-Test-Clippy, produktiver Release-Buildcheck und Formatprüfung bestehen ebenfalls. ### Tatsächliche Donation bei QSA-Cache-Updates Die beiden BF16-`DynamicSliceUpdate`-Knoten verwenden jetzt wie das gepinnte `backend/gpu/primitives.cpp` → `backend/common/copy.h` vorhandenen Speicher, wenn der Vector-Copy-Donation-Vertrag erfüllt ist. Die neue Ausgabe erhält eine eigene View-/Array-Identität auf demselben Data; der Vector-Copy-Dispatch entfällt, die originale dynamische Zeilenkopie bleibt. Prüfkriterien am Ausführungszeitpunkt: exklusiver Array-Descriptor, exklusives `Rc`/Data einschließlich GPU-Holds, identischer Eingabedescriptor, ausreichender View-Bereich und höchstens 16 KiB Überhang der **Root-Allocation**, nicht nur der kleineren View. Beide Elementtypen sind in diesem installierten Cachepfad BF16; dies ist keine generische Dtype-Regel. Der unveränderte Graph nimmt entweder festgehaltene Buffer-Eingaben oder exklusiv veränderlichen `QsaCacheInput::State` entgegen. Die verbundene Hostmethode heißt nun `qsa_indexer_rows` und gibt den echten Cache über die State-Variante hinein. Snapshots/Views bleiben durch die gemeinsame Besitzprüfung geschützt. Es gibt keinen zweiten Algorithmus und keine Donation-Einstellung für Anwender. Alle 198 bestehenden Q/K-/Hidden-Referenzfälle laufen zusätzlich durch die State-Variante mit lebenden Snapshots und anschließend exklusivem Besitz. Gleiche Ausgabe-/Zustandshashes, unveränderte Snapshot-Hashes und tatsächliche unterschiedliche bzw. identische Data-Adressen prüfen Kopieren und Donation getrennt. Die zwei zusätzlichen Durchläufe sind keine neuen unabhängigen Referenz-Fixtures. Ein zusätzlicher Test prüft Descriptor-Aliase, geteilte Storage-Snapshots, native Views, GPU-Data-Holds sowie Überhänge 0/16384/16386 Byte. Reproduktionsbelege: `local-eval-results/20260906-mtplx-port/qsa-cache-donation-check.log`. Normaler und verschärfter Lauf bestehen mit **37/37 Tests**. Kernelprüfung, Release-Test-Clippy, produktiver Release-Buildcheck und Formatprüfung bestehen. ### Allocator: Referenzfolge, Cache-Auswahl und Größenrundung `tools/mtplx-allocator-reference.py` zeichnet 101 echte modellfreie Allokations-, Freigabe-, Limit- und Clear-Ereignisse der installierten MTPLX-Runtime 0.32.2 auf. `tests/fixtures/mtplx-allocator.jsonl` hält aktive/gecachete Bytes, tatsächliche Buffergrößen und lauflokal anonymisierte physische Buffer-Identitäten fest. Es ist kein nachgebauter Python-Allocator und kein Performance-Benchmark. Die Rust-Implementierung von `backend/common/buffer_cache.h` verwendet zwei geordnete Standard-Maps anstelle der C++-Multimap plus intrusiver Zeigerliste. Sie erhält Best-Fit, älteste Einfügung bei gleicher Größe, die strikte Grenze `min(2*Anforderung, Anforderung+2*Seitengröße)`, altersbasierte Teilfreigabe und vollständiges Leeren ab 90% angeforderter Freigabe. Bei vollständigem Leeren bleibt die größenbasierte Reihenfolge erhalten. Der Replay-Test prüft alle 101 Zustandsübergänge und wiederverwendeten Buffer-Identitäten; außerdem die Grenzen beim Ändern des Cache-Limits und dessen erlaubtes kurzfristiges Überschreiten bei Freigabe. Der Cache ist noch nicht an native Ressourcen gebunden. Die Größenrundung aus `MetalAllocator::malloc` ist bereits an `Buffer::bytes` und `Buffer::untracked` der testgebundenen Schicht angeschlossen: Anforderung zuerst gegen das wirkliche Metal-`maxBufferLength` prüfen, nur oberhalb einer VM-Seite aufrunden. Auf diesem M5 Max beträgt die Seite 16384 Byte. Eine logische View erhält die angeforderte Tensorgröße; Data besitzt weiterhin die vollständige Allocation. Dadurch sehen Donation und Speicherzählung die tatsächliche Größe, während Read-/Write-Grenzen unverändert bleiben. Die native Ergänzung liest nur die Metal-Gerätegrenze; Auswahl-/Rundungslogik bleibt Rust. Der Metal-Test prüft beide vorhandenen Resource-Optionen und 1/255/256 Byte sowie die Seitengrenzen. Die Donation-Grenztests verwenden jetzt die real gerundeten Root-Größen. Kernel und Synchronisationsgrenzen bleiben unverändert. Belege: `local-eval-results/20260906-mtplx-port/allocator-policy-check.log`. Normaler und unretained Metal-Lauf bestehen mit jeweils **39/39 Tests**; Kernelprüfung, Release-Test-Clippy, produktiver Release-Buildcheck und Formatprüfung bestehen ebenfalls. Noch offen für den vollständigen Allocator: Bindung des Pools an die echte Data-Freigabe, 1-MiB-Heap für Anforderungen unter 256 Byte, Residency/Wired-Limit, Ressourcen-/GC-/Speicherlimits und deren Zähler sowie die leere Array-/Null-Buffer- Repräsentation. Die vorhandenen Resource-/Hazard-Optionen wurden nicht pauschal umgestellt; dazu gehört die noch fehlende vollständige Encoder-Abhängigkeitslogik. Dies ist noch **keine vollständige Donation-/Evaluator-Parität**: Außerhalb des QSA-Graphen fehlt die modellweite Integration dieser Regeln; ebenso andere Primitive und generische Typ-/Layoutzweige. Vollständiger Modellgraph und produktive Integration bleiben offen. Der produktive FP32-Pfad erhält durch diese testgebundene Besitzschicht keine neue Referenzzählung; keine Durchsatz- oder UI-Parität wird behauptet. ### Allocator: GPU-Ressourcenbesitz unabhängig von Data-Donation Die gemeinsame kanonische Dispatch-Schicht hält jetzt Rust-Allocation-Besitz bis zum Abschluss des zugehörigen Metal-Command-Buffers. `BufferData` besitzt eine gemeinsame Root-Allocation; GPU-Bindings halten diese Allocation, nicht Data. Damit bleibt die vorhandene referenzkonforme Donation-Prüfung unabhängig von der physischen GPU-Ressourcenhaltung. Nur der letzte Allocation-Besitzer gibt den nativen Root frei. Diese Trennung ist für die noch ausstehende Pool- Anbindung erforderlich: Ein bloßer nativer `MTLBuffer`-Retain verhindert zwar Deallokation, aber nicht die verfrühte Wiederverwendung durch einen Rust-Pool. Rust dedupliziert Root-Allocations pro Dispatch. Die bestehende native Completion-Registrierung übernimmt den Rust-Besitz atomar und setzt den Übergabezeiger auf null; bei früher Validierungs-/Pipeline-/Encoder-Ablehnung behält und bereinigt Rust ihn. Der Callback ersetzt in diesem Pfad das native Resource-Set, ohne zusätzliche Callbacks, Flushes, Commits oder Wartepausen. Der rohe ABI-Pfad ohne Rust-Owner behält seine bisherige native Haltung. Die typisierten Bindings binden zudem die Lebensdauer von Tensor-Views und Scalar-Zeigern an ihre Rust-Referenzen bis zur Übergabe. Ein modellfreier Metal-Test prüft Deskriptor-/Data-Detach bei noch uncommitteter GPU-Arbeit, Allocation-Lebensdauer, unveränderte Data-Donation, Deduplikation bei In-place-Bindings, Freigabe nach Completion, synchrone Einzel-Dispatches sowie zurückbehaltenen Besitz bei Validierungsfehlern. Beide vollständigen kanonischen Sammlungen bestehen mit **40/40 Tests**, normal und mit `DS4_METAL_UNRETAINED_COMMAND_BUFFERS=1`; alle bisherigen Referenzhashes bleiben gleich. Beleg: `local-eval-results/20260906-mtplx-port/allocation-lifetime-check.log`. Kernelprüfung, Release-Test-Clippy und produktiver Release-Buildcheck bestehen. Zu dieser Zwischenstufe war der Pool noch nicht aktiviert. Der folgende Abschnitt dokumentiert die anschließende native Anbindung; modellweiter Evaluator und produktive Integration bleiben offen. ### Allocator: Nativer Pool, Heap und Limits `Allocator` bindet die bestehende Cache-Politik jetzt an echte native Roots und deren finale Allocation-Freigabe an. Das gilt einschließlich der GPU-Besitzer des gemeinsamen Dispatch-Pfads: Solange ein Command Buffer noch auf Speicher zugreift, bleibt dieser aktiv und kann nicht als Cache-Treffer vergeben werden. Die Besitzerstruktur enthält keinen Zyklus: Der Cache besitzt native Roots, nicht die Allocation-Deskriptoren, die ihrerseits den Allocator halten. Die Rust-Seite übernimmt die vollständige bisher portierte malloc/free-Policy: Cache-Suche vor GC, ursprüngliche Best-Fit-Grenzen, aktive/gecachete/Peak-Bytes, Ressourcenzähler, Cache-Limitwechsel ohne sofortiges Leeren, Trimmen erst nach Allokation, Memory-Limit/GC-Schwelle und Ressourcenlimit. Auch die unsigned Subtraktion bei ausschließlich ressourcenbedingtem Druck bleibt erhalten. Ein Memory-Limit ist hier wie in der Referenz keine harte Ablehnung einer größeren Allokation. Anfangswerte stammen aus den tatsächlichen Metal-/sysctl- Werten und den Referenzformeln; Resource-Limit-Fallback ist 499000. Die native Ergänzung stellt nur Metal-Plattformoperationen bereit: einen 1-MiB-Heap, Buffer daraus oder als Fallback direkt vom Gerät sowie Freigaben. Rust wählt den Heap ausschließlich für Anforderungen unter 256 Byte. Die Ressourcenoptionen sind `Shared | HazardTrackingUntracked`. Die Paravirtual- Ausnahme bleibt erhalten. Null/0 Byte liefert `None`, keine künstliche Ein-Byte-Allokation; vorhandene Array-APIs müssen diese Darstellung noch modellweit übernehmen. Logische Views bewahren die ursprünglichen Tensorgrenzen auch bei gerundeten oder größeren wiederverwendeten Roots. Der native Replay-Test führt alle **101 Referenzereignisse** mit echten Allokationen aus und prüft nach jedem Schritt aktive/gecachete/Peak-Bytes, Ressourcenzahl und logische/physische Größen. Cache-Treffer müssen tatsächlich dieselben Speicheradressen zurückgeben; neue Geräteallokationen dürfen andere Adressen als beim Referenzprozess haben. Ein weiterer Test prüft 1/255/256/257- Byte-Heap-Routing, Erschöpfung der 1-MiB-Heap-Slots mit Geräte-Fallback, Memory-/Ressourcen-GC, unveränderte Zähler bei Ressourcenablehnung und echte Cache-Wiederverwendung erst nach GPU-Completion. Beide kanonischen Sammlungen bestehen mit **42/42 Tests**, normal und unretained. Beleg: `local-eval-results/20260906-mtplx-port/native-allocator-check.log`. Clippy für Release-Tests, produktiver Release-Buildcheck, Original-Kernel- und Formatprüfung bestehen. Es wurden keine Modellgewichte geladen. **Verbleibende Integration:** Residency/Wired-Limit, externe/wrapped Buffer, prozessweiter Allocator-Lebenszyklus, Routing aller kanonischen Allokationen und vollständige Encoder-Abhängigkeiten. Der Allocator wird bislang explizit von den modellfreien Tests verwendet, nicht vom vollständigen Modellpfad. Die vorhandenen Helfer werden nicht vor der Abhängigkeits-Portierung pauschal auf untracked Ressourcen umgestellt. Vollständiger Modellgraph, UI/Harness- Produktionspfad und ±2%-Performance-Abnahme bleiben weiterhin unerledigt. ### Allocator: Residency und Wired-Limits `qwen_mtplx/residency.rs` portiert die Regeln aus dem gepinnten `backend/metal/resident.cpp`: Metal-3/macOS-15-Freigabe, initiales Set mit stehender Residency-Anforderung, 5%-Standardcap mit 64-MiB-Untergrenze, Single-Set-Modus, First-Fit, Wiederverwendung leerer Sets für übergroße Allokationen und Emptiest-Fallback bei 32 Sets oder späterem Treiberfehler. Die ursprünglichen Umgebungsvariablen und deren einmalige `atoi`-Auswertung bleiben erhalten. Rust führt Budgets, Sets und gespeicherte Allokationsgrößen; die native Bridge enthält nur die Metal-Operationen. Der Allocator registriert den Heap einmal und jeden Nicht-Heap-Root bei Neuanlage. Cache-Einträge bleiben registriert/verdrahtet; tatsächliche Freigabe entfernt sie vor dem nativen Release. Wired-Limitwechsel registrieren passende bereits vorhandene Allokationen bzw. entfernen sie unter das neue Budget. Pro berührtem Set erfolgt ein Commit. Weder Freigabe noch erneutes Setzen desselben Limits befördert wartende Allokationen automatisch. Eine atomare Set-Zahl erlaubt den schnellen Queue-Attach-No-op; neue Sets werden im Test unmittelbar vor dem GPU-Commit angefügt, nicht bereits beim Allokieren. Ein nativer Test überträgt die zehn Lifecycle-Szenarien aus der ursprünglichen `tests/residency_tests.cpp` und prüft zusätzlich Cache-Verbleib, Limit-Ablehnung und tatsächliche Metal-`allocationCount`-/`containsAllocation`-Ergebnisse. Maximal rund 129 MiB werden dabei gleichzeitig verdrahtet. Die Tests prüfen Budgets, Set-Auswahlregeln und native Mitgliedschaft; gleiche Adress-/Hash- Bucket-Reihenfolgen zwischen zwei Prozessen werden damit nicht behauptet. Der Resize-Durchlauf verwendet wie die Referenz eine ungeordnete Map. Beide kanonischen Sammlungen bestehen mit **43/43 Tests**, normal und unretained; Release-Test-Clippy, produktiver Release-Buildcheck, Original-Kernel- und Formatprüfung bestehen. Beleg: `local-eval-results/20260906-mtplx-port/residency-check.log`. **Weiter offen:** automatische Anbindung an sämtliche tatsächlichen Encoder- Commit-Pfade, externe/wrapped Buffer, prozessweiter Besitzer, vollständiges Routing der Modellallokationen und Encoder-Abhängigkeiten. Der explizite Allocator ist weiterhin testgebunden; es gibt keinen neuen Gesamtmodell- Benchmark und weiterhin keinen Nachweis der verlangten ±2%-Parität. ### Submission: Residency an tatsächlichen Commit-Grenzen `qwen_mtplx/submission.rs` hält Queue, Allocator und den bereits angefügten Set-Index über mehrere Command-Batches hinweg. Ein Scope registriert einen threadlokalen, synchronen Rust-Callback vor dem tatsächlichen nativen Commit. Beim Erstellen werden vorhandene Sets angefügt; vor jedem späteren Commit werden nur neu entstandene Sets ergänzt. Nested Scopes können den Besitzer nicht überschreiben. Finish/Drop lassen den Besitzer bis nach dem Drain leben und entfernen dann den Callback; danach erbt der Legacy-Pfad keinen Hook. Alle zwölf bisherigen direkten Command-Buffer-Commit-Stellen der Bridge laufen jetzt durch einen gemeinsamen Einstieg, einschließlich Flush, Readback, Cleanup und GLM-Streaming-Split. Der Hook ist nur im kanonischen Scope aktiv und auf dessen Encoding-Thread sowie die Haupt-Queue begrenzt; andere Queues bleiben ausgenommen. Metal-Residency-Set-Commits bleiben eigene Operationen. Es entstehen keine zusätzlichen Command Buffers, Flushes oder Wartepausen. Ein Quelltest schützt gegen erneute direkte Commit-Umgehungen. Der native Test prüft nachträglich erzeugte Sets, Flush, Eval, Finish, Drop, native interne Batch-Beendigung mit anschließendem synchronen Einzel-Dispatch und das Entfernen des Hooks. Die kanonische Sammlung besteht normal und unretained mit **45/45 Tests**. Release-Test-Clippy, produktiver Release- Buildcheck, Original-Kernel- und Formatprüfung bestehen ebenfalls. Beleg: `local-eval-results/20260906-mtplx-port/submission-check.log`. Dies schließt den bisher manuellen Residency-Attach für diesen testgebundenen Scope, **nicht** den gesamten MTPLX-Encoder. Weiter offen sind die genaue Input-/Output-Klassifikation aller Bindings, Barrier-Epochen, ConcurrentContext, Encoder-Fences/Completion-Bereinigung, Ops-/Byte-Commit-Schwellen und vollständige Modell-/Produktintegration. Der produktive Qwen-Graph nutzt den Scope noch nicht; Gesamtmodell-Performance und ±2%-Abnahme bleiben unbewiesen. ### Encoder: abhängige Ausführung, Fences und Shared Events `qwen_mtplx/encoder.rs` portiert die zusammengehörige Steuerung aus MTPLXs gepinntem Runtime-`backend/metal/device.cpp`, einschließlich `event.cpp` und der verbrauchenden Fehlersemantik aus `error.h`. Rust besitzt eine eigene Queue und unretained Command Buffers. Jeder Compute-Encoder ist Concurrent; Rust entscheidet anhand tatsächlicher Metal-Buffer-Identitäten über Read/Write- Barrieren, aktuelle Barrier-Epochen, deferred ConcurrentContext-Ausgänge und deduplizierte Fence-Waits zwischen Encodern. Completion entfernt einen Producer nur, wenn dessen Fence noch aktuell ist. Temporäre Ressourcen werden aus den encoderübergreifenden Mengen entfernt und bis Completion gehalten. Shared-Event-Wait und -Signal beenden den aktuellen Encoder. Completion führt zuerst den Benutzer-Callback aus, übernimmt den ersten gültigen fremden Wait-Event-Fehler und danach gegebenenfalls einen GPU-Fehler. Signal-Events teilen den konsumierbaren Fehlerzustand des Encoders; bei GPU-Fehlern werden sie zusätzlich auf der CPU signalisiert, damit wartende Queues nicht hängen. Synchronize wirft/entnimmt den Fehler; der Destruktor wartet, ohne ihn zu entnehmen. Fence-, Event- und Buffer-Holds bleiben bis Completion gültig. Die ursprünglichen Commit-Schwellen und ihre einmaligen Umgebungsvariablen werden übernommen. **Korrektur der bisherigen Byte-Bezeichnung:** Der gepinnte Code addiert `array.data_size()` ohne Multiplikation mit `item_size`. Laut `array.h` sind das Elemente, keine Bytes. Auf Max/Ultra gilt daher strikt `ops > 50 || (data_size >> 20) > 50`. Ein Buffer zählt beim ersten Input-Eintrag je Encoder; die Summen werden erst beim Command-Commit zurückgesetzt. Raw- Buffer-Bindings zählen als encoderübergreifende Ein- und Ausgänge, ändern aber weder die Barrier-Epochen noch den Größenzähler. Es gibt keine zusätzlichen automatischen Sleeps oder pro-Layer-Waits. Die native Bridge benutzt denselben validierenden Pipeline-/Binding-/Dispatch- Code für den bisherigen und den explizit übergebenen Encoder. Sie entscheidet nicht über Abhängigkeiten, Batching oder Fehlerweitergabe. Der neue Rust- Encoder lehnt Tensor-Bindings ohne explizite Input/Output/Raw-Rolle ab, statt aus Buffergrößen oder Kernel-Namen Zugriffsrollen zu erraten. Drei neue Checks prüfen Barrier-/Commit-Epochen, disjunkte Concurrent-Outputs, abhängige untracked Kopien über mehrere Encoder und asynchrone Command Buffers, Fence-Deduplizierung/Completion-Rennen, temporäre Buffer, beide Dispatch- Geometrien sowie reale Shared-Event-Transfers zwischen zwei Queues. Fehler- Completion wird gezielt mit einem synthetischen GPU-Status geprüft, ohne einen GPU-Hänger auszulösen. Die gesamte Sammlung besteht normal mit **48/48** und unretained mit **48/48 Tests**; Clippy, produktiver Release-Buildcheck und Original-Kernel-Abgleich bestehen. Beleg: `local-eval-results/20260906-mtplx-port/encoder-check.log`. **Nicht abgeschlossen:** Dieser Encoder ist weiterhin testgebunden. Vollständige Zugriffsrollen und exakte Array-`data_size`-Metadaten aller Operator-Bindings, Routing der Allokationen, Stream-/Scheduler-/Graph-Integration einschließlich aller Eval- und Completion-Grenzen sowie der komplette Modellpfad fehlen noch. Die große bestehende Kernelsammlung läuft weiterhin über den bisherigen Dispatch-Pfad; nur die neuen Encoder-Tests benutzen die eigene Queue. Der alte Submission-Scope ist damit noch keine Produktintegration. P05 und der gesamte Paritätsaudit bleiben offen; keine neue UI-/Gesamtmodell- oder ±2%-Abnahme. ### Operator-Routing: Normen und zusammenhängende MoE-Kette Ein threadgebundener `Scope` verbindet die vorhandenen Operatorfunktionen jetzt mit dem eigenen Concurrent-Encoder und demselben gepoolten, untracked Allocator. Er fügt keine Dispatch-/Eval-Grenzen ein. Nested Scopes werden abgelehnt; nach dem Scope erbt der bisherige Pfad weder Encoder noch Allocator. Der Besitzer bleibt über mehrere Operationsketten hinweg bestehen und wartet beim Abbau. Die Dispatch-Implementierung und die vorhandenen Fixture-Auswertungen werden wiederverwendet, nicht als zweiter Operatorpfad nachgebaut. Explizite Ein-/Ausgangsrollen und Elementspannen sind für die gesamte Norm-/MoE-Kette übernommen: Softmax/Top-10-Router, Argsort mit Multi-Block-Merge, Gather/Unsort, Gate/Up und SwiGLU, Grouped-/Gated-RMS, BF16/FP32-Casts, Affine-QMV/QMM einschließlich Split-K, Gather-QMM einschließlich sortiertem RHS und Broadcast-Indizes, Stock-/Fused-MoE sowie Shared Expert und Gate. Geslicte Inputs zählen wie `backend/common/slicing.cpp` ihre adressierte Elementspanne, nicht die volle Allokation oder nur die Zahl logischer Werte. Broadcast-Indizes behalten ihre tatsächliche Speicherspanne. Zwei bisherige `setBytes`-Ersatzbindungen sind durch die ursprünglichen skalaren Array-Inputs ersetzt: das Einheitsgewicht für ungewichtete RMSNorm und der Divisor in GatherSort. Sortier- und Split-K-/Reduktions-Scratch werden an den ursprünglichen Stellen als Backend-Temporaries registriert. Ihre Lebensdauer und ihr Ausschluss aus den encoderübergreifenden Ressourcenmengen laufen damit über den portierten Encoder, nicht nur über zurückgegebene Rust-Bufferlisten. Original-Kernel, Rundungsfolgen und Geometrien bleiben unverändert. Neun vorhandene Fixture-Gruppen werden ohne Abschwächung ihrer Ausgabehash- Prüfungen jeweils im bisherigen und im neuen Encoder ausgeführt: 78 Affine, 40 Gather-QMM, 123 Argsort, 7 GatherSort, 16 Router, 10 Gate/Up, 25 Normen, 21 SwitchGLU und 220 MoE — insgesamt **540 Referenzfälle in beiden Encodern**. Das sind zusätzliche Ausführungen vorhandener Fälle, keine neuen unabhängigen Referenz-Fixtures. Die Tests unterscheiden native Legacy-Busy- Zähler ausdrücklich vom Commit-Zähler der eigenen Queue. Der neue Scope-Test prüft zudem tatsächliche Pool-Allokation, Cache-Rückgabe, den Gate/Up- Speicherspannenzähler und genau eine erforderliche Barrier ohne Zwischencommit. Die gesamte kanonische Sammlung besteht mit **49/49 Tests** sowohl normal als auch mit unretained Legacy-Command-Buffers. Release-Test-Clippy, produktiver Release-Buildcheck, Format-/Diff-Prüfung und Original-Kernel-Abgleich bestehen. Beleg: `local-eval-results/20260906-mtplx-port/operator-encoder-check.log`. **Weiter offen:** GDN-/QSA-Operator-Routing, allgemeine Array-Metadaten/Donation, vollständige Stream-/Evaluator-/Graph-Anbindung und deren tatsächliche Eval-, Commit- und Completion-Grenzen sowie der produktive Gesamtmodellpfad. Ein manuell abgegrenzter Operator-Testbatch beweist nicht die Scheduling-Parität eines gesamten MTPLX-Chats. Der eigene Encoder ist noch nicht mit der normalen UI-/Harness-Instrumentation verbunden. Die ±2%-Abnahme bleibt ausstehend. ### Operator-Routing: zusammenhängende GDN-Kette GDN verwendet nun ebenfalls den gemeinsamen Dispatch mit expliziten Input-/ Output-Rollen und Array-Elementspannen: Conv/Mask/Cache, Q/K-L2-Norm, compute_g, Sigmoid, rekurrentes Delta-Update, Fused-Step und Fused-Output. Der bisherige direkte native Fused-Step-Aufruf entfällt. Projektionen und Gated-Norm verwenden die bereits angebundenen Operatoren; Original-Kernel und Geometrien bleiben unverändert. Binäre skalare Operanden und das CustomKernel-T-Argument sind echte skalare Array-Inputs, keine `setBytes`-Ersatzbindungen. `backend/metal/slicing.cpp::concatenate_gpu` bestimmt den Conv-Fenster-Aufbau: disjunkte Output-Slices mit ihrer jeweiligen `data_size`, eine Concurrent-Region für beide Kopien und anschließender Dependency-Join. Ein RAII-Guard stellt den Join auch bei vorzeitigem Fehler sicher. CustomKernel-Eingangskopien werden in Input-Reihenfolge nach der Output-Allokation ausgeführt und nach dem Dispatch als Backend-Temporaries registriert. Die fehlende Conv-State-Kopie im Fused-Step liegt jetzt hinter der Eingangsprojektion statt davor. Die vier bestehenden Gruppen mit 80 Delta-Update-, 2 laufenden Fused-Step-, 130 Staged- und 264 Forward-Fällen laufen jetzt jeweils in beiden Encodern. Zusammen mit Norm/MoE sind das **1.016 vorhandene Referenzfälle in beiden Encodern**, ohne neue oder abgeschwächte Referenz-Hashes. Die Forward-Fälle prüfen auch fortgesetzte Zustände, Nullzustände, Masken, gültige Längen, Projektionslayouts und die gewählten Fusionszweige. Die gesamte Sammlung besteht normal mit **49/49 Tests (35,79 s)** und mit unretained Command Buffers mit **49/49 Tests (35,28 s)**. Release-Test-Clippy, produktiver Release-Buildcheck, Format-/Diff-Prüfung und Original-Kernel-Abgleich bestehen. Beleg: `local-eval-results/20260906-mtplx-port/gdn-encoder-check.log`. **Weiter offen:** QSA-Operator-Routing, allgemeine Array-/Donation-Verträge, der vollständige Evaluator mit tatsächlichen Eval-/Commit-/Completion-Grenzen, Stream-Anbindung, UI-/Harness-Instrumentation und produktiver Gesamtmodellpfad. Diese GDN-Integration ist noch kein vollständiger Modellgraph und keine Performance-Paritätsabnahme. P05 und der Gesamtauftrag bleiben offen. ### QSA-Cache-Kopien und kompilierte Cache-Fenster am Encoder Die gemeinsamen QSA-Kopierfunktionen tragen jetzt explizite Array-Metadaten: statische Source-Slices zählen ihre adressierte Elementspanne; Slice-Updates binden das vollständige Zielarray, Concatenate dagegen die logische Größe seines Output-Slices. Dynamische Kopien erhalten beide vollständigen Array- `data_size`-Werte vom Aufrufer, unabhängig von der kopierten Zeilenzahl. Der Encoder-Test prüft genau diese Unterscheidung sowie die Ablehnung zu kleiner Metadaten. Konstanten, die im Original Arrays sind, bleiben skalare Arrays; die dynamischen Offset-Arrays sind Inputs und Backend-Temporaries. Zero-Fill, COW-/General-Kopien, die kompilierten Frontier-Operationen und die fused Query-/Pool-Vorbereitung benutzen explizite Ein-/Ausgangsrollen. Die KV-Vergrößerung verwendet für ihre disjunkten Concatenate-Kopien den originalen Concurrent-Kontext. Kernelquellen und Dispatch-Geometrien wurden nicht verändert. Die vorhandenen 12 Backing-/Dynamic-Copy- und 26 Cache-Window- Fälle laufen mit identischen Hash-Prüfungen in beiden Encodern; insgesamt sind damit **1.054 bestehende Referenzfälle in beiden Encoder-Pfaden** abgedeckt. Gesamtsammlung: **49/49 normal (35,53 s)** und **49/49 unretained (35,11 s)**. Release-Test-Clippy, produktiver Release-Buildcheck, Format-/Diff-Prüfung und Original-Kernel-Abgleich bestehen. Beleg: `local-eval-results/20260906-mtplx-port/qsa-copy-encoder-check.log`. **Weiter offen:** Das ist noch nicht die komplette QSA-Kette. Insbesondere eager RoPE/Pooling, Score-Produzenten und Selektoren, sämtliche verbleibenden Concurrent-/Eval-Grenzen und der vollständige Graph-/Produktionspfad müssen weiter angebunden werden. Die neuen Cache-Fälle ersetzen weder die vollständige Modellprüfung noch die geforderte Performance-Abnahme. ### QSA-Vorbereitung, Cache-Fortsetzung und fused Selektor am Encoder Die eager Query-/Pool-Vorbereitung verwendet jetzt ebenfalls explizite Ein-/Ausgangsrollen und die adressierten Elementspannen. Alle drei RoPE- Concatenates haben die ursprünglichen Concurrent-Regionen samt anschließenden Dependency-Joins. Positions-, Amplituden- und Mittelwertskalierung verwenden skalare Array-Operanden; die BF16-/FP32-Grenzen bleiben unverändert. Die vorhandenen Norm-, Cast- und General-Copy-Operatoren werden weiterverwendet. Der fused Selektor und seine Chunk-Zusammenführung sind ebenfalls angebunden. Die drei Frontier-Arrays werden wie im Original separat angelegt statt als drei Views derselben Allokation. Seine private Score-Ausgabe bleibt ein CustomKernel-Output, keine als Backend-Temporary deklarierte Arbeitskopie. Numerische Kernelquellen und Dispatch-Geometrien sind unverändert. Die vorhandenen 210 Vorbereitungs-/Projektions-, 88 laufenden Cache- und 75 Selektor-/Chunk-Fälle werden nun in beiden Encodern geprüft, einschließlich Trim/Reserve/Restore und Descriptor-/Data-Alias-Verhalten. Insgesamt laufen damit **1.427 bestehende Referenzfälle in beiden Encoder-Pfaden**. Die Cache- Tests enthalten auch reine Metadatenoperationen; ihre manuellen Testgrenzen sind ausdrücklich keine Behauptung identischer Modell-Eval-Grenzen. Gesamtsammlung: **49/49 normal (36,34 s)** und **49/49 unretained (36,33 s)**. Release-Test-Clippy, produktiver Release-Buildcheck, Format-/Diff-Prüfung und Original-Kernel-Abgleich bestehen. Beleg: `local-eval-results/20260906-mtplx-port/qsa-prepare-encoder-check.log`. **Weiter offen:** getrennte Score-Produzenten, eager Selektions-/Ausgabepfade, komplette Graph-/Stream-/Evaluator- und Produktionsanbindung samt Instrumentation. Die bisherige minimale Platzhalter-Allokation für leere Selektor-Arrays ist unverändert; ein allgemeiner Null-Storage-Array-Vertrag fehlt weiterhin. Keine dieser Operator-Prüfungen ist eine vollständige Modell- oder Performance- Abnahme. Der gesamte Paritätsauftrag bleibt offen. ### QSA-Score-Produzenten und verbundener Prefill am Encoder Beide Score-Produzenten, Prefill-Top-k und die bestehende Chunk-Verkettung laufen jetzt über den unabhängigen Encoder. Der FP32-Pfad bindet GEMV, Steel/NAX, Split-K samt Akkumulation, Maximum und Reduktion mit expliziten Array-Rollen und Elementspannen. Maximum/Divide verwenden echte skalare Arrays. Matmul allokiert seinen Output vor den Transpose-Kopien; diese Kopien und Split-K- Scratch werden nach ihren Konsumenten als Backend-Temporaries registriert. AsType- und Score-Zwischenergebnisse bleiben normale Graph-Arrays. Der MPP-Pfad behält seine stridefähigen Eingaben ohne zusätzliche Kopien. Prefill-Top-k allokiert alle Outputs vor der erforderlichen General-Copy, registriert diese Arbeitskopie nach dem Dispatch und verwendet drei separate Frontier-Arrays. Kernelquellen, Spezialisierungen und Dispatch-Geometrien bleiben unverändert. Vorhandene Operatoren und Referenzfälle werden wiederverwendet. Die 384 FP32-Score-, 146 MPP/Top-k/Prefill- und 96 gemischten Producer-Fälle bestehen nun in beiden Encodern mit unveränderten Originalhashes. Insgesamt: **2.053 bestehende Referenzfälle in beiden Encoder-Pfaden**. Die bestehenden manuellen Testgrenzen ergeben jeweils genau ein Submission; sie behaupten ausdrücklich keine identischen vollständigen Modell-Eval-Grenzen. Gesamtsammlung: **49/49 normal (36,76 s)** und **49/49 unretained (37,19 s)**. Release-Test-Clippy, produktiver Release-Buildcheck, Format-/Diff-Prüfung und Original-Kernel-Abgleich bestehen. Beleg: `local-eval-results/20260906-mtplx-port/qsa-score-encoder-check.log`. **Weiter offen:** eager Selektions-/Ausgabepfade, vollständiger Graph, Streams, Evaluator, allgemeiner Null-Storage-Vertrag und Produktionsanbindung samt Instrumentation. Die produktive Qwen-Ausführung ist nicht umgeschaltet. Diese Operator-Prüfungen ersetzen weder Modell- noch Performance-Abnahme; der vollständige Paritätsauftrag bleibt offen. ### Eager QSA und verbundener Indexer am Encoder Maskierung, Ranking und sämtliche eager Ausgabevarianten verwenden nun explizite Array-Rollen/-Spannen und skalare Array-Operanden. Die negative Unendlichkeit wird zwischen Kacheln geteilt. Jedes ursprüngliche `mx.eval(top_t)` wartet auf der tatsächlich aktiven Queue; der unabhängige Pfad eröffnet dafür keinen Legacy-Command-Buffer. Tiled-Index-, Decode-Tail-, Rows-Gather- und Dense- Concatenates besitzen ihre ursprünglichen Concurrent-Regionen samt Join. Zwei frühere Verkürzungen sind entfernt: Dense-Padding wird vor Concatenate materialisiert, und Rows-Gather erzeugt seine beiden separaten Arange-Ausdrücke. Vorhandene Originaloperatoren werden wiederverwendet, keine Kernelkörper oder Spezialisierungen verändert. Der feste Indexer-Graph hält Input-/Sibling-Data nun über Completion-Callbacks der aktiven Queue; primäre beziehungsweise gespendete Output-Data bleiben ausgeschlossen. Graph-Concatenates sind ebenfalls angebunden, und kompilierte Frontiers sind vier separate int32-Arrays. Die bestehenden **540 eager Fälle und 200 laufenden Indexer-Aufrufe** laufen jetzt in beiden Encodern, einschließlich kompilierter Varianten, Cache- Fortsetzungen, Selektions-/State-Hashes, Graph-Engagement und expliziter Tile- Eval-Anzahlen. Insgesamt **2.793 bestehende Dual-Encoder-Referenzfälle**. Der vorhandene Data-Ownership-Test prüft zusätzlich beide Queues, Donation- Ausschluss und das Ausbleiben einer Submission beim bloßen Registrieren von Holds. Gesamtsammlung: **49/49 normal (40,19 s)** und **49/49 unretained (40,20 s)**. Release-Test-Clippy, produktiver Release-Buildcheck, Original-Kernel-Abgleich, Format-/Diff-Prüfung bestehen. Beide Referenz-Checkouts sind sauber und auf den festgehaltenen Commits. Beleg: `local-eval-results/20260906-mtplx-port/qsa-eager-encoder-check.log`. **Weiter offen:** vollständiger Modellgraph und allgemeiner Stream-/Evaluator- Scheduler, insbesondere die automatische Commit-Entscheidung nach Original- Primitiven; allgemeiner Null-Storage-Vertrag und Produktionsanbindung samt Instrumentation. Die manuellen Fixture-Grenzen ersetzen diese nicht. Der produktive Qwen-Pfad ist weiterhin nicht umgeschaltet, und die vollständige Modell-/Performance-Abnahme aller drei Modelle bleibt offen. ### Primitive-Commits und Scheduler am festen Indexer-Tape (2026-09-07) Der Rust-Scheduler übernimmt die FIFO-Worker je CPU-Stream, früheste Fehler, nicht konsumierende Event-Fehlerweitergabe, Synchronisation und abarbeitendes Shutdown aus der von MTPLX verwendeten Runtime 0.32.2. Verwendet werden stdlib und die vorhandene Shared-Event-Bridge, keine weitere Abhängigkeit. GPU-Encoding bleibt auf dem aufrufenden Thread wie in der Referenz. Der feste Indexer-Tape prüft die originale Commit-Bedingung jetzt nach dem vollständigen Primitiv, nicht pro Kernel. Input-/Sibling-Data und Backend-Holds sind davor an den betreffenden Command Buffer gebunden. Automatische Commits zählen laufende Aufgaben, deren Completion beziehungsweise fehlgeschlagene Übergabe den Zähler wieder ausgleicht. Die originale Druckbedingung `tasks > 10 || (active_memory > memory_limit && tasks > 0)` finalisiert den hier einzigen offenen GPU-Stream und wartet auf Fortschritt; keine neuen Sleeps. Dabei fiel eine veraltete Testannahme auf: Der verbundene Indexer erwartete pauschal die manuellen Tile-/Final-Submissions. Zwei volle Prefill-Fälle (`compiled_s12_qk0_step0` und `compiled_s12_qk1_step0`) benötigen zusätzlich je einen automatischen Commit: nach 17 Dispatches mit 57.469.227 beziehungsweise 55.246.572 gezählten Elementen gilt `(data_size >> 20) > 50`. Diese beiden Fall-Erwartungen werden unabhängig vom Zähler der expliziten Synchronisationen geprüft; alle übrigen verbundenen Fälle erwarten null automatische Commits. Die alte Prüfung wurde nicht durch eine pauschale größere Toleranz ersetzt. Output-, Cache- und Graph-Hashes bleiben unverändert. **Prüfung:** vier zusätzliche Scheduler-/Primitive-Tests; Gesamtsammlung **53/53 normal (42,53 s)** und **53/53 unretained (41,97 s)**. Release-Test-Clippy, produktiver Release-Buildcheck, Format-/Diff-Prüfung und Original-Kernel-Abgleich bestehen. Beide Referenz-Checkouts sauber auf den festgehaltenen Commits. Beleg: `local-eval-results/20260907-mtplx-port/scheduler-check.log`. **Weiter offen:** allgemeine Device-/TLS-Stream-Verwaltung, vollständiger Evaluator mit streamübergreifendem Tape, CPU-Primitive-Encoding, vollständiger Qwen-Modellgraph, allgemeiner Null-Storage-Vertrag und Produktionsanbindung samt Instrumentation. Die CPU-Worker sind bisher modellfrei geprüft, nicht im Produktionsmodell angebunden. Der kanonische Port bleibt `cfg(test)`; Produkt-Qwen, UI/Harness-Verhalten und Gesamt-Performance sind nicht abgenommen. Der vollständige Auftrag und die anschließende Drei-Modell-Matrix bleiben offen. ### CPU-Dispatch und gemeinsame Primitive-Ownership (2026-09-07) Der CPU-CommandEncoder-Teil aus `backend/cpu/encoder.h` ist im bestehenden Rust-Scheduler ergänzt: jeder zehnte Dispatch zählt eine laufende Aufgabe; eine separate nachfolgende FIFO-Aufgabe meldet den Abschluss auch bei einem Fehler im eigentlichen Dispatch. Ein abgewiesenes Enqueue lässt keinen neuen Task-Zähler zurück. Die Cleanup-Aufgabe aus `backend/cpu/eval.cpp` zählt dabei ebenfalls als Dispatch und hält Input-/Sibling-Data sowie Backend-Temporaries bis hinter die zuvor eingereichte Arbeit. CPU- und GPU-Evaluator verwenden dafür jetzt dieselbe Data-Auswahlfunktion: Deduplication nach Data-Identität, primärer Output einschließlich gespendeter Input-Data ausgeschlossen. CPU-Temporaries behalten ihre vollständigen nativen Deskriptoren; der private Send-Wrapper erlaubt ausschließlich deren Freigabe auf dem Worker, keinen Buffer-Zugriff. `Buffer` selbst bleibt nicht Send/Sync. Es gibt keine neue Abhängigkeit, keinen Metal-Kernel- oder Produktionswechsel. Gezielte Prüfungen: **5/5 Scheduler-Tests**, GPU-Evaluator-Ownership **1/1**, verbundener Indexer mit allen 200 Fällen in beiden Encodern **1/1 normal** (2,54 s) und **1/1 unretained** (2,50 s), jeweils unveränderte Ausgabe-/State- Hashes. Release-Test-Clippy, Produkt-Buildcheck, Originalquellen-Abgleich und Format-/Diff-Prüfung bestehen. Die vollständige 53er-Sammlung des vorherigen Schrittes wurde hierfür nicht als neue Gesamtabnahme ausgegeben. Beleg: `local-eval-results/20260907-mtplx-port/cpu-scheduler-check.log`. **Weiter offen:** Device-/TLS-Stream-Registry und allgemeiner Evaluator samt Modellgraph; CPU-Dispatch-/Hold-Regeln sind vorhanden, CPU-Modelloperationen und deren Routing aber noch nicht verbunden. Produktionsanbindung und gesamte Modell-/Performance-Abnahme bleiben unverändert offen. Der Stream-Abgleich ist keine Behauptung, dass bereits eine vollständige Registry implementiert sei. ### CPU-/GPU-Stream-Verwaltung und Indexer-Anbindung (2026-09-07) Ein Runtime-eigener Stream-Besitzer verbindet jetzt die vorhandenen CPU- und GPU-Encoder für den installierten Ein-CPU-/Ein-Metal-Backend-Vertrag. Die Regeln aus `stream.h/cpp` sind abgebildet: getrennte Defaults pro Thread/Device, threadlokale Stream-Templates mit verzögerter Auflösung, normale threadgebundene Streams und sequentiell threadübergreifend verwendbare globale Streams. CPU-IDs bleiben wegen des gemeinsamen Schedulers über Context-Wechsel eindeutig. Die Registry hält ihren Lock weder beim Encoding noch bei Dispatch oder Wait. Ein ausgewählter GPU-Encoder benutzt weiterhin den vorhandenen Rc/RefCell-/TLS- Operatorpfad und denselben Allocator; pro Stream-Auswahl wird kein neuer Encoder oder neuer GPU-Queue-Besitzer erzeugt. Für die sichere Rückgabe aus einer Auswahl werden genau ein starker und null schwache Rc-Besitzer verlangt. Gleichzeitige mutable Nutzung wird abgewiesen, Fehler und Unwinding geben den Encoder zurück. Ein TLS-Cleanup gibt lokale Encoder auch beim Thread-Ende ohne explizites Clear frei. Explizites Clear erhält wie die Referenz die dann gegebenenfalls veralteten Default-/Template-Handles und Stream-Metadaten; globale GPU-Encoder werden dabei nur vom Scheduler-Main-Thread entfernt, globale CPU-Encoder nicht. Wait/Signal, Finalize und Synchronize verwenden die existierenden CPU-FIFOs und Metal-Events. Die streamübergreifende Lastbegrenzung finalisiert alle offenen GPU-Streams in der ursprünglichen Device-/Index-Reihenfolge, bevor sie auf Fortschritt wartet. Der gezielte Test verbindet zwei GPU-Queues per Event und hält elf gezählte CPU-Aufgaben dahinter zurück. Erst das Einreichen beider GPU-Queues löst die Kette. Eine fünfsekündige Sicherung würde einen kaputten Finalize-All-Pfad fehlschlagen lassen statt den Test endlos hängen zu lassen. Die vorhandene laufende **200-Fall-Indexer-Folge** nutzt nun im unabhängigen Pfad einen registrierten Default-GPU-Stream statt eines alleinstehenden Scope; Legacy-Gegenpfad und sämtliche Ausgabe-/State-/Commit-Erwartungen bleiben erhalten. Zwei neue Stream-Tests prüfen außerdem Defaults, Thread-Zuordnung, Template- Auflösung, Cleanup, Fehler-Rückgabe, Thread-Wechsel und echte Kernel-Kopien. **Prüfung:** vollständige modellfreie Sammlung **57/57 normal (41,39 s)** und **57/57 unretained (41,56 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung und Original-Kernel-Abgleich bestehen; beide Referenzen sauber auf den festgehaltenen Commits. Beleg: `local-eval-results/20260907-mtplx-port/stream-check.log`. **Weiter offen:** vollständiger allgemeiner Array-/Evaluator-Graph mit streamübergreifenden Abhängigkeiten, CPU-Modelloperationen, Compile-Cache-Clear- Anbindung, Null-Storage-Vertrag und kompletter Modell-/Produktionspfad samt Instrumentation. Die Registry ist bisher im kanonischen Test-Port angebunden, nicht in der UI-Inferenz. Dieser Schritt belegt weder den kalten UI-Ping noch Modell-/Performance-Parität; die anschließende Drei-Modell-Matrix bleibt offen. ### Evaluator-Events und beide Inter-Stream-Fence-Pfade (2026-09-07) Der Port enthält jetzt die Event-/Fence-Verträge aus `event.h`, `backend/metal/event.cpp` und `backend/metal/fence.cpp`. Graph-Event-Kopien teilen native Event-/Fehlerzustände, behalten aber ihren eigenen Wert-Snapshot und Ursprungsstream. Host-Waits prüfen den gemeinsamen Fehler vor und nach dem Wait. Diese Events sind von den internen MTLFences des Command Encoders getrennt. Inter-Stream-Fences unterstützen beide Referenzzweige. Standardmäßig bleibt SharedEvent-Synchronisation aktiv. Der optionale Fast-Pfad verlangt unverändert `MLX_METAL_FAST_SYNCH` und Metal3/macOS15-Unterstützung. Er verwendet die bereits in der gepinnten Metallib vorhandenen Originalfunktionen `input_coherent`, `fence_update` und `fence_wait`, keine nachgebauten Kernel. GPU-Waits registrieren die konsumierten Arrays als Outputs; GPU-Updates erhalten die ursprüngliche Cross-Device-Coherence-Stufe und explizite Barrier. CPU-Operationen verwenden den separaten atomaren Timestamp mit SeqCst-Zugriffen, ohne neue Sleeps/Yields. Fence-Kopien teilen den Update-Zähler, während eingereihte Operationen ihren jeweiligen Zählerwert erfassen. CPU-Aufgaben und Command-Completion-Holds halten den privaten Timestamp-Speicher bis zum tatsächlichen Abschluss. Die Metal-Bridge akzeptiert nun wie die Referenz leere Dispatch-Grids. Ein gezielter Test prüft den leeren Coherence-Dispatch sowie eine BF16-Spanne, die auf zwei uint32-Wörter aufgerundet wird. Das prüft einen realen Speicher mit `data_size=0`, nicht den weiterhin offenen allgemeinen Null-Storage-Vertrag. Die betroffene Rust-FFI wird derzeit ausschließlich vom `cfg(test)`-Port benutzt. Drei neue Prüfungen decken Event-Snapshots/Fehler, kleine leere/teilwortige Coherence-Grids und eine **CPU → GPU → GPU → CPU**-Kette in beiden Fence-Modi mit exakten Daten und Freigabe nach Completion ab. Eine ausschließlich im Test vorhandene fünfsekündige Sicherung löst Wartebedingungen bei einem Fehler auf; sie griff nicht ein. Neue modellfreie Gesamtsammlung: **60/60 normal (41,38 s)** und **60/60 unretained (41,47 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung, Originalquellen- und Metallib-Hash- Prüfung bestehen. Beide Referenzen sind sauber auf den gepinnten Commits. Beleg: `local-eval-results/20260907-mtplx-port/graph-sync-check.log`. **Weiter offen:** vollständiger Array-/Evaluator-Graph, der diese Abhängigkeiten aus den Modelloperationen erzeugt; CPU-Modelloperationen, Compile-Cache-Clear, Null-Storage und vollständige Qwen-Produktionsanbindung samt Instrumentation. Der Fast-Modus wird nicht als Optimierung eingeschaltet. UI-Verhalten und Gesamt-Performance wurden nicht neu gemessen; die vollständige Drei-Modell- Abnahme bleibt offen. ### Gemeinsame Graph-Planung und Stream-Abhängigkeiten (2026-09-07) `qwen_mtplx/eval.rs` übernimmt die Traversierung aus dem gepinnten `transforms.cpp::eval_impl`: Auswahl des Synchronizer-Streams, DFS-Gradzählung für alle Geschwister-Ausgaben, BFS mit Breitenlimit und DFS-Fortsetzung sowie umgekehrte Ausführungsreihenfolge. Tape-Einträge identifizieren die tatsächlich gewählte Ausgabe, nicht bloß deren Producer; diese Wahl ist für Data-Holds und Donation relevant. `MLX_BFS_MAX_WIDTH` wird wie in `utils.h` einmalig mit `get_var`/`atoi`-Semantik gelesen (Default 20), nicht mehr lokal fest verdrahtet. Die Traversierung berücksichtigt Unscheduled/Evaluated/Available und das vom Aufrufer gelieferte effektive Tracer-Flag. Bereits ausgewertete, nicht mehr getracete Primitive werden einschließlich ihrer Geschwister abgelöst. Async- Tracer und fehlende Primitive behalten die Referenzfehler. Stream-Abhängigkeiten werden pro Ausgabe ermittelt; der Cross-Device-Bedarf wird über alle Konsumenten vereinigt. Das ist noch keine allgemeine Array-Speicher- oder Transform-Runtime. Der bisherige separate QSA-Scheduler ist entfernt. Der bestehende kompilierte Indexer erzeugt sein wiederverwendetes Tape jetzt über diesen gemeinsamen Planer. Sein einzelner logischer Stream wird beim Replay weiterhin auf dem Encoder des Aufrufers ausgeführt; die Planung erzeugt keine zusätzliche Queue. Alle bestehenden Ergebnis-, State-, Lifetime- und Commit-Prüfungen bleiben unverändert. Keine Metal-Kernel, Flush- oder Prefill-Sonderregeln geändert. Drei neue modellfreie Strukturprüfungen decken Breiten-/Sibling-Reihenfolge, Stream-/Device-Abhängigkeiten sowie Status-/Detach-/Tracer-Fehler ab. Ihre Erwartungen wurden aus der gepinnten Traversierung abgeleitet, nicht als neue Live-Runtime-Trace ausgegeben. Gesamtsammlung **63/63 normal (40,70 s)** und **63/63 unretained (40,90 s)**; Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung und Originalquellen-/Metallib-Hash-Prüfung bestanden. Beide Referenz-Checkouts sind unverändert auf den festgehaltenen Commits. Beleg: `local-eval-results/20260907-mtplx-port/graph-tape-check.log`. **Weiter offen:** allgemeine Array-Daten-/Primitive-Ausführung mit dem gesamten Eval-Epilog und Fehler-Cleanup, Verknüpfung der hier ermittelten Abhängigkeiten mit Graph-Events/Fences, CPU-Modelloperationen, Compile-Cache-Clear, Null-Storage und vollständiger Qwen-Produktionspfad samt Instrumentation. Der kanonische Port bleibt `cfg(test)`; der UI-Modellpfad ist damit nicht umgestellt. Keine neuen Modell-/Performance-Läufe, kein Paritäts-Pass und keine Rücknahme eines Referenzbestandteils. Die vollständige Drei-Modell-Abnahme bleibt offen. ### Gemeinsamer Eval-/Async-Eval-Ablauf mit Abschluss und Fehler-Cleanup (2026-09-07) Der gemeinsame Planer ist jetzt mit dem Ausführungs-Kontrollfluss aus `transforms.cpp::eval_impl`, `eval` und `async_eval` verbunden. Der Evaluator verwendet die vorhandene Stream-Registry, CPU-FIFOs, Encoder, Graph-Events und beide Graph-Fence-Backends. GPU-Primitive laufen auf dem aufrufenden Thread im Scope ihres Streams, nicht in einem neu eingeführten Worker-Pool. Innerhalb einer Auswertung werden die geplanten Stream-Abhängigkeiten per Fence abgewickelt; zwischen Async-Auswertungen über das gespeicherte Event. Bereits signalisierten Events wird beim Ablösen noch ihr Fehler entnommen. Ein fehlgeschlagenes Ablösen lässt Event und Status bestehen. Status, primäre Ausgabe und Geschwister werden in Referenzreihenfolge aktualisiert. Der Abschluss signalisiert die Eval-Events und finalisiert alle offenen GPU-Streams; der synchrone Aufruf wartet auf den Synchronizer, der asynchrone nicht. Leere oder bereits geplante Async-Ausgaben erzeugen keine neue Auswertung/Submission. Bei einem Primitivfehler werden die beteiligten Events signalisiert und alle betroffenen Streams synchronisiert. Cleanup-Fehler ersetzen nicht die Ursache. Dasselbe Cleanup läuft beim Rust-Unwinding; danach wird der ursprüngliche Panic weitergereicht. Der lokale Synchronizer wird in allen Rückgabewegen entfernt. Frühere erfolgreiche Knoten bleiben ausgewertet, so dass ein Retry nur die fehlgeschlagenen Knoten erneut ausführt. Gemeinsame Data-Hold-Helfer werden für den bestehenden QSA-Pfad und den neuen Kontrollfluss wiederverwendet; CPU-Cleanup behält seine Zehner-Taskzählung. Der Synchronizer benötigt keinen Datenpuffer. Drei neue modellfreie Prüfungen verbinden echte kleine CPU-/GPU-Operationen: CPU → GPU mit Geschwister-Ausgaben → zweite GPU-Queue → CPU; eine absichtlich noch laufende Async-Ausgabe als Eingabe der nächsten Auswertung; Fehler und Panic mit vollständigem Drain/Retry; Tracer-Donation-Schutz und behaltene Topologie. Die zehnsekündige Deadlock-Sicherung gilt ausschließlich für diese winzigen Unit-Tests und beendet bei einem Hänger deren Prozess; sie griff nicht ein und ersetzt nicht den Startup-/Progress-Watchdog der Modell-Harness. Zusätzlich prüft der bestehende Event-Test einen Fehler trotz signalisiertem Event. Gezielte neue Tests: **3/3 SharedEvent (0,14 s)** und separat **3/3 Fast-Fence (0,12 s)**. Gesamtsammlung **66/66 normal (41,35 s)** und **66/66 unretained (41,58 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung und Originalquellen-/Metallib-Hash-Prüfung bestanden. Keine Shader-/Bridge-Änderung; beide Referenzen sauber auf ihren Pins. Beleg: `local-eval-results/20260907-mtplx-port/eval-execution-check.log`. **Abgrenzung:** Das ist der gemeinsame Ausführungs-Kontrollfluss, noch nicht der vollständige Array-/Modellport. Primitive werden als konkrete Rust-Operationen eingespeist; materialisierte Buffer mit Elementzahl/Elementgröße bleiben beim Aufrufer. Allgemeine Descriptor-/Graph-Ownership, Shapes/Strides, Freigabe bei letzter Graph-Referenz und Null-Storage müssen noch mit diesem Ablauf verbunden werden. Der derzeitige Tracer-Schutz hält Input-Data vorübergehend und verhindert Donation; die vollständige Descriptor-Referenzsemantik ist damit nicht belegt. CPU-Modelloperationen, Compile-Cache-Clear und vollständiger Qwen-Produktionspfad samt Instrumentation bleiben offen. QSA nutzt weiter seinen kompilierten Replay innerhalb des Caller-Batches, nicht einen zusätzlichen Eval-Abschluss pro Indexer-Aufruf. Der gesamte kanonische Port bleibt `cfg(test)`. Keine UI-/Modell-/Performance-Abnahme und keine Schließung des Drei-Modell-Ziels. ### Leere materialisierte Daten und Null-Bindings (2026-09-07) Der kanonische Buffer-Pfad kann nun leere Data-Objekte ohne Metal-Allokation darstellen. `MetalAllocator::malloc(0)` der gepinnten Runtime liefert null; `array::set_data` erzeugt trotzdem eine eigene Data-Identität. Entsprechend erzeugt `Buffer::bytes(0)` im Test-Port einen leeren nativen Descriptor mit `buffer=nil`, nicht einen Dummy-Puffer. Allokator-, Cache-, Peak- und Ressourcen- Zähler bleiben unverändert. `Allocator::allocate(0)` liefert weiterhin `None`. Der vorhandene Descriptor-/Data-/Allocation-Lebenszyklus wird wiederverwendet: unabhängige leere Buffer haben verschiedene Data-Identitäten, Views teilen Data und bekommen ihre eigene Descriptor-ID. Die native View-/Free-Verwaltung bleibt zuständig; es gibt keine zweite Speicherverwaltung. Leere Reads/Writes sind gültig, nichtleere oder außerhalb liegende Zugriffe bleiben Fehler. Eine leere View kann außerdem einen vorhandenen nichtleeren Speicher behalten und am Ende dieser Allokation liegen; sie wird nicht stillschweigend durch Null-Data ersetzt. Die kanonische Metal-Bindung akzeptiert jetzt die von `device.cpp` verwendeten Null-Bindings und leere Views. Null-Ressourcen bleiben wie in der Referenz Teil der RAW-/WAR-Abhängigkeitsmengen; ihr `data_size` ist null. Die Objective-C- Fallback-Hold-Menge übernimmt nur tatsächliche Metal-Buffer, da `NSSet` kein nil aufnehmen darf. `tensor_contents` gibt für Null-Storage direkt null zurück, ohne Pointer-Arithmetik darauf auszuführen. Die unveränderten Originalkernel `input_coherent`, `fence_update` und `fence_wait` laufen in den entsprechenden leeren Grids/Fence-Pfaden; kein Ersatzkernel und kein zusätzlicher Flush. Zwei neue Prüfungen decken Identitäten, Freigabe, Grenzen, unveränderte Allokatorzähler, Null-Abhängigkeiten, leere Tail-Views sowie beide nativen Ownership-Pfade ab. Bestehende Fence-/Evaluator-Prüfungen enthalten nun echten Null-Storage, einschließlich GPU → CPU. Gezielte Prüfungen je **1/1 (0,06 s)**; erweiterter Fast-Fence-Evaluator **3/3 (0,11 s)**. Gesamtsammlung **68/68 normal (41,23 s)** und **68/68 unretained (41,44 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung und Originalquellen-/Metallib-Hash- Prüfung bestanden; Referenz-Checkouts unverändert auf den Pins. Beleg: `local-eval-results/20260907-mtplx-port/empty-storage-check.log`. **Abgrenzung:** Damit ist der leere Buffer-/Binding-Vertrag verbunden, nicht automatisch jeder Zero-Shape-Zweig sämtlicher Array-Operationen. Allgemeine Array-Descriptor-/Graph-Ownership, Shapes/Strides, Freigabe bei letzter Graph-Referenz, CPU-Modelloperationen und der vollständige Modell-/Produktions- pfad bleiben offen. Die neue Buffer-Erzeugung ist an den kanonischen `cfg(test)`- Pfad gebunden; die produktive Inferenz ist noch nicht umgestellt. Keine neuen Modelldownloads oder Modell-/Performance-Läufe; das Drei-Modell-/2%-Ziel bleibt offen. ### Gemeinsame Array-Ownership im Lazy-Evaluator (2026-09-07) Die externe `Vec>` des allgemeinen Evaluators ist entfernt. `eval`/`async_eval` arbeiten jetzt unmittelbar auf geteilten Array-Deskriptoren; Primitive materialisieren ihre vorhandenen Ausgabedeskriptoren. Status, Events, Eingaben, Geschwister, Ausgabeposition und Data gehören diesem Owner. Der kompilierte QSA-Planner bleibt derselbe; seine vorhandenen materialisierten Cache-Arrays verwenden ebenfalls den gemeinsamen Storage-/Descriptor-Owner. Die Ownership-Regeln stammen aus `array.cpp`/`array.h` der gepinnten Runtime: Descriptor-Kopien teilen Identität, separate Data-Views nicht; Donation verlangt exklusive Descriptor- und Data-Ownership. Geschwister halten sich gegenseitig und ihre jeweiligen Eingaben. Beim letzten äußeren Verweis werden die Zyklen aufgelöst und lange Eingabeketten iterativ freigegeben. `detach` entfernt bei allen Geschwistern Primitive, Eingaben, Geschwister und Ausgabeposition, ohne Status oder Events zu löschen. Data-/Allocation-/GPU-Completion-Holds bleiben in der bestehenden Speicher-/Encoder-Verwaltung; keine zweite Allokatorlogik. Für die Planung entsteht nur ein schwacher Topologie-Index, keine zusätzliche starke Referenz auf jedes Zwischenergebnis. Der Ausführungstape hält die von MTPLX ausgewählten Ausgaben; nach Detach und letztem Verbraucher verschwinden die Eingabedeskriptoren. Planungs-Detach wirkt unmittelbar, auch vor einem späteren Planungsfehler. Bei Ausführungsfehlern bleibt der Rest-Tape bis nach dem Event-/Stream-Cleanup erhalten. Tracer halten während des Primitivaufrufs jetzt zusätzliche **Descriptor-Verweise**, nicht ersatzweise zusätzliche Data. Zwei neue reine Ownership-Tests prüfen die letzte äußere Geschwisterreferenz, 30.000 Knoten mit behaltenem Zwischenknoten, 10.000 doppelte Geschwisterstufen und vollständigen Detach. Die bestehenden drei verbundenen Evaluatorprüfungen sind auf Array-Ownership umgestellt; eine vierte prüft Donation ohne künstliche Arena-Referenzen, Freigabe nach letztem Verbraucher und unabhängig behaltene Geschwister-Ausgaben. Der QSA-Donation-Test prüft zusätzlich einen direkten Descriptor-Alias. Ergebnis-, Cache-, Lifetime- und Commit-Assertions des vorhandenen Kernel-/Indexer-Bestands bleiben erhalten. Prüfstand: **71/71 normal (42,16 s)** und **71/71 unretained (42,15 s)**; abschließender Fast-Fence-Evaluator **4/4 (0,14 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung und Originalquellen-/Metallib-Hash-Prüfung bestanden. Beide Referenz-Checkouts sauber auf ihren Pins; keine Shader- oder native Bridge-Änderung in diesem Schritt. Diese Zeiten sind Testlaufzeiten, keine Modell-Performance. Beleg: `local-eval-results/20260907-mtplx-port/array-ownership-eval-check.log`. **Abgrenzung:** Das verbindet die Descriptor-/Graph-Lebensdauer mit dem Ausführungskontrollfluss, schließt aber nicht den gesamten Array-/Modellport. Allgemeine Shapes/Strides/Dtypes/Flags, konkrete Modellprimitive und ihre vollständige Verbindung, CPU-Modelloperationen, Compile-Cache-Clear sowie die Produktionsanbindung samt Instrumentation bleiben offen. Elementzahl und Elementgröße werden ausdrücklich mit Materialisierungen übergeben; das ist noch kein allgemeiner Shape-Inferenzpfad. Der kanonische Port bleibt `cfg(test)`. Keine neuen Modellgewichte, keine Gesamtmodell-Messung, keine Paritätsabnahme. ### Typisierte Array-Geometrie vor der Auswertung (2026-09-07) Der allgemeine Evaluator übernimmt keine freie Kombination von `data_size` und `itemsize` mehr. Der bisherige `Value`-Transporttyp ist entfernt; Shapes und echte Dtypes stehen bereits am unscheduled Ausgabedeskriptor. Primitive materialisieren dessen Daten über `set_data`. Die gemeinsame Array-Geometrie enthält Shape, kanonische Strides, Elementzahl, Dtype, Data-Elementzahl und Contiguity-Flags. BF16 und FP16 bleiben verschiedene Typen trotz gleicher Bytebreite; alle 14 Dtype-Werte der gepinnten Runtime sind abgebildet. Die Regeln folgen `ArrayDesc::init`, `array::set_data`, `array::make_arrays` und `dtype.h`: skalare Shapes haben ein Element, Shapes mit Null-Dimensionen null; kanonische Strides werden von hinten aufgebaut. Negative Achsen werden relativ zum Rank ausgewertet. Vor Materialisierung sind die drei Flags true; danach wird Column-Contiguity aus der Form bestimmt. Ein neuer Primitivoutput übernimmt nicht versehentlich die materialisierten Flags seines Inputs. GPU-Primitive weisen Float64 an Eingaben oder Ausgaben zurück; die reine CPU-Deskriptorkonstruktion erlaubt es. Leere Ausgabelisten erzeugen keine Deskriptoren und führen diese GPU-Prüfung entsprechend nicht aus. Materialisierungen mit zu kleinem Buffer sind Fehler und lassen vorhandene Daten/Geometrie unverändert; Größenberechnungen sind geprüft. Die bestehende Data-/Descriptor-/Completion-Verwaltung bleibt unverändert. QSA-Backing-Arrays sind als BF16 typisiert; ihre vorhandene logische Cache-Geometrie und Head- Strides bleiben beim Cache. Das ist noch keine Umstellung jedes Cache-Views auf allgemeine Array-Shape-/Offset-Operationen. Im Evaluator leiten sich die Fence-Elementzahl und Bytebreite jetzt aus dem typisierten Descriptor ab. Eine neue reine Geometrieprüfung deckt die 14 Dtypes mit skalaren, leeren, einheitsdimensionalen und mehrdimensionalen Formen sowie Grenzen/Flags ab. Eine neue modellfreie Metal-Prüfung deckt echte Materialisierung, Fehler ohne Datenverlust, Aliase und leeren Speicher ab. Der bestehende Evaluator- und QSA-Testbestand ist auf den typisierten Vertrag umgestellt; keine bisherigen Ergebnis-/Lebensdauer-/Commit-Prüfungen entfernt. Prüfstand: **73/73 normal (42,01 s)** und **73/73 unretained (41,66 s)**; Fast-Fence-Evaluator **4/4 (0,14 s)**. Gezielte Array-Prüfungen einschließlich kleiner Metal-Allokationen **4/4 (0,07 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff- und Originalquellen-/Metallib-Prüfung bestanden. Referenzen sauber auf den bisherigen Pins; keine Shader-/Bridge-Änderung. Beleg: `local-eval-results/20260907-mtplx-port/typed-array-geometry-check.log`. **Abgrenzung:** Allgemeine strided Views mit Byte-Offsets, negative Strides, Broadcast/Transpose/Reshape-Operationen, Dtype-Promotion/Conversions und alle Modellprimitive sind damit nicht als vollständig portiert abgenommen. Auch CPU-Modelloperationen, Compile-Cache-Clear, vollständiger Qwen-Modell-/Produktions- pfad und Instrumentation bleiben offen. Der Port ist weiterhin `cfg(test)`; keine Modell- oder 2%-Performance-Abnahme und keine neuen Modellgewichte. ### Geteilte Views und Byte-Offsets bis zur Metal-Bindung (2026-09-07) Array-Deskriptoren tragen jetzt ihren eigenen Byte-Offset über demselben geteilten Backing. `set_strided_data` übernimmt Strides/Flags/Data-Größe und einen Byte-Offset; `copy_shared_buffer` addiert wie `array.cpp` einen Offset in **Elementen des Ziel-Dtypes** zum vorhandenen Offset. Beide verwenden die bestehenden Descriptor-/Data-/Allocation-Owner, keine zusätzlichen GPU-Views oder Allokationen. Ungültige Spannen/Offsets werden vor einer Mutation abgewiesen. `set_data` setzt den Offset zurück, behält aber wie die Referenz die Strides. Die gemeinsamen materialisierten Backend-Operationen Slice, Broadcast und Transpose sind aus `backend/common/slicing.cpp`, `broadcasting.cpp` und `common.cpp::Transpose::eval` angeschlossen. Sie erhalten bereits inferierte Ausgabe-Shapes und normalisierte Achsen/Indizes. Negative Strides und Broadcast- Strides von null bleiben erhalten; Flags/Data-Größe werden nach den jeweiligen Referenzregeln berechnet. Leeres Slice/Broadcast erzeugt leere eigene Data statt das Eingabebacking zu halten. Generelles Reshape und Dtype-View/Conversion sind noch nicht durch diese drei Backend-Operationen abgedeckt. Der kanonische Metal-Binding-Vertrag hat nun einen zusätzlichen Byte-Offset. Rust reicht ihn an `setBuffer` weiter; die native Brücke prüft Basisgrenzen und Additionsüberlauf vor der Submission. Inline-Bytes haben weiterhin Offset null. Die Ressourcenabhängigkeiten bleiben pro Backing, nicht pro View. Auch der Fast-Fence-Coherence-Aufruf des allgemeinen Evaluators bindet den Array-Offset; bestehende Buffer-Aufrufer verwenden unverändert Offset null. Kein zusätzlicher Flush, Wait, Puffer oder veränderter Originalkernel. Die neue überwachte Prüfung verbindet Reverse-Slice → Transpose → Slice → Broadcast → Original-Metal-Copy im gemeinsamen Evaluator. Das Ergebnis ist bytegenau geprüft; bis zur tatsächlichen Copy bleiben Allokatorzähler unverändert. Zusätzlich: positive Offset-View über GPU → CPU, leere/ungültige Views, Freigabe der ursprünglichen Graphreferenz. Bestehende Array-Tests prüfen explizite negative Strides, Ziel-Dtype-Offseteinheiten, Selbst-Sharing, Fehler ohne Mutation und Offset-Reset. Native Grenztests prüfen, dass ein ungültiger Binding-Offset den Ressourcen-Owner nicht übernimmt. Der vorhandene kleine Test-Watchdog ist wiederverwendet, keine neue Modell-Gesamtlaufzeitgrenze. Prüfstand: **74/74 normal (41,18 s)** und **74/74 unretained (41,35 s)**. Die neue View-Kette besteht separat normal **1/1 (0,08 s)** und mit Fast-Fences **1/1 (0,06 s)**; der bestehende Fast-Fence-Evaluator **4/4 (0,15 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung und Originalquellen- /Metallib-Hash-Prüfung bestanden; Referenz-Checkouts sauber auf den Pins. Beleg: `local-eval-results/20260907-mtplx-port/array-views-offsets-check.log`. **Abgrenzung:** Das ist eine verbundene Backend-/Ownership-/Binding-Erweiterung, keine vollständige Array-Ops-API oder Qwen-Modellintegration. Allgemeines Reshape, Dtype-View/Promotion/Conversions, weitere Modellprimitive, vollständige logische QSA-Graphanbindung, CPU-Modelloperationen, Compile-Cache-Clear und produktive Instrumentation bleiben offen. Der kanonische Port bleibt `cfg(test)`; keine Gesamtmodell-/UI-/2%-Performance-Abnahme und keine neuen Modellgewichte. ### Reshape: gemeinsames Backing oder Original-General-Copy (2026-09-07) `views::reshape` übernimmt `common.cpp::prepare_reshape` und `metal/copy.cpp::reshape_gpu`: gleiche Elementzahl/Dtype, Single-Array-Collapse mit INT32_MAX-Grenze, passende geteilte Strides einschließlich negativer und Broadcast-Strides; unveränderte Data-Größe/Offsets und referenzgleiche Flags. Leere und row-contiguous Inputs teilen das Backing ohne GPU-Allokation. Der Copy-Fall kollabiert dagegen Input- und kanonische Output-Strides gemeinsam in der **Input-Shape**, allokiert die Ausgabe und dispatcht die unveränderten General-Copy-Kernel aus der übernommenen Metallib. Rust selektiert Rang, Large-Index-Namen und Work-per-thread wie die Referenz; Inline-Slices werden über den vorhandenen Binding-Helfer mit ihrer tatsächlichen Byte-Länge gebunden. Kein zusätzlicher Flush oder Wait, keine neue Ownership-Schicht. Der überwachte Test verbindet Transpose → Reshape im gemeinsamen Evaluator: 13 GPU-Dtypes × vier Shape-Fälle, mit positivem Backing-Offset, Singleton-Achsen, g2/g3/gn2-Kopien und unabhängig indizierter bytegenauer Ausgabeprüfung. Zusätzlich: Reverse-Strides beim geteilten Reshape, skalare und nichtuniforme Broadcasts (Share versus Copy), leere Arrays und Größenfehler ohne Mutation. Das sind kleine modellfreie Funktionstests; Large-Index-Kopien oberhalb INT32_MAX werden hier nicht mit großen Allokationen ausgeführt. Prüfstand: **75/75 normal (41,85 s)**, **75/75 unretained (41,63 s)**; View-/Reshape-Ketten mit Fast-Fences **2/2 (0,09 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung und Quellen-/Metallib-Hash-Prüfung bestanden; beide Referenz-Checkouts sauber auf den Pins. Befehle/Ergebnisse: `local-eval-results/20260907-mtplx-port/reshape-check.log`. Der kanonische Port bleibt `cfg(test)`. Dtype-View/Promotion/Conversions, weitere Modellprimitive, vollständige logische QSA-Graphanbindung, CPU- Modelloperationen, Compile-Cache-Clear, produktive Instrumentation und der vollständige Qwen-Modellpfad sind weiterhin offen. Der Reshape-Backend-Port ist ausdrücklich keine Produktions-, UI- oder Gesamtmodell-Performance-Abnahme. ### AsType und Dtype-View am gemeinsamen Copy-/Evaluator-Pfad (2026-09-07) Die tatsächlich verwendeten Qwen-Referenzaufrufe wechseln u.a. Router-Indizes, QSA-Pooled-Scores und RoPE-Zwischenwerte (`models/qwen4_exp.py`: 345, 803–804, 1633–1658, 1945, 1965–1968). Der kanonische Rust-Backend-Port bildet jetzt `gpu/primitives.cpp::AsType::eval_gpu` und `View::eval_gpu` ab, ohne dafür Konvertierungsshader neu zu schreiben. AsType selektiert Vector anhand des **contiguous**-Flags (nicht nur row- contiguous), erhält dabei Strides/Flags/physische Data-Größe und übernimmt donierbare gleich breite Speicher innerhalb der referenzierten 16-KiB-Grenze. Bei gleichem Dtype entfällt dann der Dispatch; bei verschiedenem Dtype werden Werte tatsächlich in place konvertiert. Andere Layouts gehen durch General Copy. Vector-Work-per-thread richtet sich nach Zieldtype und 65536-Schwelle; Large-Index-Namen und 2D-Grid-Faktorisierung folgen der gepinnten Referenz. Dtype-View prüft skalare/letzte-Achsen-Bytegrößen. Gleiche Breite, geeignete kleinere Breite oder row-contiguous Input teilen das Backing mit angepassten Strides/Data-Größen. Andernfalls kopiert der originale General-Kernel zunächst in einen dichten temporären Input-Dtype-Puffer, den die Ausgabe anschließend teilt. Der General-Copy-Pfad wird auch von Reshape wiederverwendet. Seine 1024-Thread-Bedingung wird jetzt am tatsächlichen Pipeline-State geprüft; Vector nutzt dessen Maximum. Die native Lookup-Routine ist aus dem vorhandenen Dispatch extrahiert und zwischen Abfrage/Encoding geteilt. Kein zusätzlicher GPU-Command, Flush, Wait oder geänderter Metal-Kernel. Neue überwachte Evaluator-Prüfung: alle 169 GPU-Dtype-Konvertierungspaare mit unabhängig kodierten 0/1-Werten; Vector-Schwellen 65535/65536/65537, Donation mit/ohne Konvertierung, negative Strides, spaltenkontiguierliche und Broadcast- Backings, Dtype-View-Sharing und -Copy, skalare/ungültige/leere Ausgaben. Large-Index-Grid und originale Large-Pipelines sind ohne große GPU-Allokation geprüft; keine Ausführung von Multi-GB-Copies daraus behauptet. Prüfstand: **76/76 normal (41,86 s)**, **76/76 unretained (41,29 s)** und **3/3 View-/Reshape-/Konvertierungsketten mit Fast-Fences (0,15 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung und Quellen-/ Metallib-Hash-Prüfung bestanden; beide Referenz-Checkouts sauber auf den Pins. Beleg: `local-eval-results/20260907-mtplx-port/dtype-copy-view-check.log`. **Offen bleiben** die vollständige Array-Ops-API samt Promotion, weitere Modellprimitive/logische QSA-Anbindung, CPU-Modelloperationen, Compile-Cache- Clear und die Produktionsintegration mit Instrumentation. Weiterhin `cfg(test)`; keine Gesamtmodell-/UI-/2%-Performance-Abnahme. ### Graph-eigene Array-Operationen statt externer Test-Zuordnung (2026-09-07) Array-Deskriptoren können jetzt ihre konkrete Operation besitzen. Der neue `ops::evaluate` verwendet unverändert den gemeinsamen Eval-/Async-Eval-Pfad, liest den Payload aber aus dem Graphen, nicht aus einer externen ID-/Callback- Tabelle. Detach gibt auch diesen Payload frei. Die bisherigen spezialisierten Fixture-Callbacks bleiben verfügbar; der Produktionsmodellpfad ist noch nicht umgeschaltet. Lazy-Konstruktoren für Reshape, Transpose, Broadcast, AsType, Dtype-View, ExpandDims und Squeeze übernehmen Shape-/Achsenprüfung, negative Achsen, Reshape-Inferenz und die jeweiligen No-op-Regeln aus `ops.cpp`. ExpandDims fügt Stride 1 ein, Squeeze entfernt nur die ausgewählten Strides; Flags, Data-Größe und Offset bleiben geteilt wie in `common.cpp`. CPU-Ausführung ist hier nur für diese gemeinsamen Views angeschlossen; CPU-Copy/Conversions bleiben ausdrücklich offen und werden nicht still auf die GPU umgeleitet. Der überwachte Test baut Qwens `pooled.astype(float32).swapaxes(1,2)[:,None]` aus diesen Konstruktoren und verbindet weitere Reshape-/View-/Broadcast- Verbraucher einschließlich GPU→CPU und Async→Sync. Vor Evaluation entstehen keine GPU-Allokationen. Er prüft erwartete Shape/Strides, bytegenaue Werte, No-op-Identitäten/Fehler und die Freigabe ursprünglicher Arrays und Operations- Payloads. Das ist eine eigenständig ausführbare Layout-Graphfolge, noch keine Anbindung des vollständigen QSA-Caches oder Qwen-Modells. Prüfstand: **77/77 normal (41,19 s)**, **77/77 unretained (41,47 s)**; neuer Graph mit Fast-Fences **1/1 (0,06 s)**. Release-Test-Clippy, Produkt- Buildcheck, Format-/Diff- und Originalquellen-/Metallib-Prüfung bestanden. Beleg: `local-eval-results/20260907-mtplx-port/owned-operations-check.log`. ### Slice-Normalisierung und Contiguous für Cache-Fenster (2026-09-07) Der graph-eigene Slice-Konstruktor übernimmt die Normalisierung von Start/Stop, Vorwärts-/Rückwärts-Schritten und Singleton-Strides aus `ops.cpp`. Die No-op- Entscheidung verwendet das ursprüngliche Vorzeichen vor der Singleton- Vereinfachung. Rangfehler und Schritt null werden vor Graphanlage abgewiesen. Ausführung nutzt den vorhandenen geteilten Slice-Backend, ohne neuen Kernel. `Contiguous` ist wie in `ops.cpp` immer ein eigener Knoten. Sein GPU-Backend teilt row-contiguous oder ausdrücklich erlaubte column-contiguous Inputs nur innerhalb der ursprünglichen 16-KiB-Backing-Grenze; sonst verwendet es den gemeinsamen Original-General-Copy. Diese Entscheidung ist für Qwens `cache[0] = contiguous(conv_input[:, -n_keep:, :])` relevant, damit ein kleines Fenster nicht unbegrenzt ein großes Prefill-Backing hält. Der überwachte Graph-Test prüft Slice-Werte/Identitäten/Strides, leere und skalare Inputs, negative Grenzen/Schritte und Fehler. Dieselbe Zwei-Zeilen- Cache-Ansicht wird einmal aus kleinem Backing geteilt und einmal aus großem Backing kopiert; Column-Major erlauben/verbieten ist separat geprüft. Keine Modellgewichte geladen; vollständige QSA-/Modellintegration und Performance- Abnahme bleiben offen, der Port bleibt `cfg(test)`. Prüfstand: **78/78 normale modellfreie Tests (41,85 s)**. Die beiden graph- eigenen Operationsprüfungen bestehen zusätzlich **2/2 unretained (0,09 s)** und **2/2 Fast-Fences (0,08 s)**; keine vollständige unretained-Wiederholung in diesem Schritt. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff- Prüfung und Quellen-/Metallib-Hashes bestanden. Beleg: `local-eval-results/20260907-mtplx-port/slice-contiguous-check.log`. ### RMSNorm als rechnende Graphoperation (2026-09-07) Der Array-Payload-Pfad unterstützt jetzt mehrere Eingaben; RMSNorm trägt Input und Gewicht als normale Graphkanten. Der GPU-Konstruktor folgt `fast.cpp` einschließlich der für RMSNorm gültigen Floating-Promotion, vorgeschalteter AsType-Knoten und skalarem Eins-Gewicht im ungewichteten Fall. CPU-Fallback- Arithmetik bleibt offen und wird ausdrücklich abgewiesen, nicht auf GPU umgeleitet. Der Backend übernimmt `metal/normalization.cpp` statt pauschal `contiguous` aufzurufen: passende zusammenhängende letzte Dimension und zulässiger vorletzter Stride; anschließend Donation oder gleichartiges Backing. Andere Layouts werden einmal dicht kopiert, und dieses Backing wird zum Output. Die Zeilenzahl folgt der physischen Data-Größe, nicht der virtuellen Shape. Input-/Gewicht-/Output-Offsets und Gewicht-Stride gehen in den Originalkernel. Der frühere BF16-Helper und der neue Graphbackend teilen denselben Dispatch; kein neuer Normalisierungsshader, keine neue Flush-/Wait-Grenze. Neue überwachte Prüfung: FP16/BF16/FP32, Breiten 1/128/4096/4097, vorhandene Input-Aliase versus letzter Verbraucher, Broadcast-Backings, notwendige Input-Copy, strided/versetzte Gewichte und Inputs, ungewichtete Norm, BF16+FP16→FP32 sowie ungültige Shapes. Die vorhandenen BF16-Modul-/QSA-/GDN- Fixtures prüfen zusätzlich den gemeinsam umgestellten Dispatch. Das bleibt ein kanonischer `cfg(test)`-Port; vollständige Modellintegration und der Gesamtmodell-Performance-Nachweis sind nicht damit erreicht. Prüfstand: **79/79 normal (41,87 s)** und **79/79 unretained (41,49 s)**; RMSNorm-Graph mit Fast-Fences **1/1 (0,08 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff- und Originalquellen-/Metallib-Prüfung bestanden. Beleg: `local-eval-results/20260907-mtplx-port/graph-rms-norm-check.log`. ### Quantisierte BF16-Projektionen als Graphoperation (2026-09-07) Der normale transponierte Affine-Linear-Pfad der installierten Qwen-Gewichte ist jetzt eine Operation mit vier Graphkanten (x, W, scales, biases). Output- Allokation vor der Eingabevorbereitung und `ensure_row_contiguous_matrix` folgen `metal/quantized.cpp`: nur die letzten beiden Strides entscheiden über die notwendige General-Copy; kein Contiguous-Slack-Kriterium. Kopien werden als Encoder-Temporaries bis zum GPU-Abschluss gehalten. Graph und bestehende Modul-Fixtures benutzen denselben Affine-Dispatcher: QMV/Quad/Wide, QMM/NAX/Split-K und die Split-Reduktion bleiben unverändert. Die Eingaben erhalten ihre tatsächlichen Byte-Offsets und Array-Data-Größen für Bindings und Submission-Zähler. Keine neuen Shader, Flushes oder Waits. Der Graphzweig ist ausdrücklich BF16 mit zweidimensionalen 4/8-Bit-Gewichten, Gruppengröße 32/64. Andere Dtypes und echte batched/expert-Matmul-Graphzweige sind noch offen; sie werden nicht stillschweigend flachgerechnet. Die neue überwachte Prüfung führt alle **78** bestehenden Referenz-Fixtures jeweils dicht, mit führendem Storage-Offset und mit strided Eingaben aus. Alle vier Eingaben werden variiert; x behält über ExpandDims eine zusätzliche Batch-Dimension, ohne vorab per Reshape dicht kopiert zu werden. **234/234 Outputs sind exakt** gegenüber den gepinnten Referenz-Hashes. Kein Modell geladen, kein Download, kein Gesamtmodell-Performance-Vergleich. Prüfstand: **80/80 normal (42,51 s)** und **80/80 unretained (42,62 s)**; der neue Graph-Test mit Fast-Fences **1/1 (0,99 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff- und Originalquellen-/Metallib-Prüfung bestanden. Produktintegration und vollständige Modelloperationen bleiben offen; dieser Graph ist weiterhin `cfg(test)`. Prüfbeleg: `local-eval-results/20260907-mtplx-port/graph-quantized-linear-check.log`. ### Elementweise Unary-Operationen im Graph (2026-09-07) Negative, Square, Exp, Sigmoid, Tanh, Sqrt und Rsqrt sind jetzt eigene Graph-Payloads. Konstruktoren folgen den jeweiligen `ops.cpp`-Typregeln: Negative/Square erhalten den Typ, die übrigen verwenden `at_least_float` mit vorgeschaltetem AsType; Negative/Bool und Sigmoid/Complex werden wie in der Referenz abgewiesen. CPU-Arithmetik bleibt ausdrücklich unportiert. Der gemeinsame Backend folgt `metal/unary.cpp`: physische Data-Größe bei zusammenhängendem Backing, `v`/`vn`-Wechsel bei 65536 Elementen, `v2` für große zusammenhängende Daten, sonst zusammengefasste Dimensionen und `gn1`/`gn4large`. Kernel-Maximalgruppen und Original-Grid-Regeln werden verwendet. Inputs und Outputs tragen ihre Byte-Offsets und Data-Größen. Die Original-Metallib wird nicht verändert. `set_unary_output_data` ist mit AsType geteilt: Donation nur bei eindeutiger Ownership, gleicher Elementbreite und höchstens 16 KiB zusätzlichem Backing; sonst physisches gleichartiges Backing bei Contiguous oder dichter Output für allgemeine Strides. Der bisherige Single-Array-Collapse von Reshape wird ebenfalls wiederverwendet, nicht mit dem Joint-Copy-Collapse vermischt. Der überwachte Test prüft exakte dyadische Werte für FP16/BF16/FP32 bei 0/1/65535/65536/65537 Elementen, mit und ohne Alias, sowie transponierte, strided, negative, Broadcast- und Offset-Views, übergroße Backings, Integer-Square und Integer→Float-Sqrt. Eine anfänglich falsche Testannahme zur Donation von Reverse-Views wurde anhand `check_contiguity` korrigiert: negative Strides zählen dort nicht zur positiven physischen Contiguity; der Backend erzeugte bereits korrekt einen neuen dichten Output. Große >UINT32-Allokationen werden mit diesem Test nicht behauptet. Prüfstand: **81/81 normal (43,88 s)** und **81/81 unretained (42,99 s)**; Unary mit Fast-Fences **1/1 (0,41 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung und unveränderte Originalquellen/Metallib bestätigt. Produktgraph und vollständige Modellintegration bleiben offen. Prüfbeleg: `local-eval-results/20260907-mtplx-port/graph-unary-check.log`. ### Binäre Graphoperationen und gemeinsame Typ-Promotion (2026-09-07) Add/Subtract/Multiply/Divide/Maximum/Minimum/LogAddExp laufen jetzt als binäre Graph-Payloads durch denselben Evaluator. Ihre Konstruktoren übernehmen `ops.cpp`: Typ-Promotion, gegebenenfalls `at_least_float`, AsType beider Eingaben und Broadcasting einschließlich der Null-Dimensionen. Die vollständige Promotion der 14 Referenztypen ist gemeinsam in Dtype implementiert und gegen alle **196** Einträge der gepinnten `dtype.cpp`- Tabelle geprüft. RMSNorm und Unary benutzen die gemeinsamen Typregeln statt eigener Teilabbildungen; ihre bestehenden Prüfungen bleiben erhalten. Der Binary-Backend übernimmt `common/binary.h` und `metal/binary.cpp`: Scalar/Scalar, Scalar/Vector, Vector/Scalar, gemeinsame Row-/Column-Vector- Layouts und General. Scalar/Scalar allokiert ein neues physisches Element; die übrigen Fälle erhalten referenzgleiche Donation-Priorität und Strides. General kann einen passenden dichten Input übernehmen. Elementbreite, Ownership und 16-KiB-Slack werden gemeinsam mit Unary/AsType geprüft. General-Dispatch verwendet den Joint-Collapse von Input A, Input B und Output; derselbe verallgemeinerte Helfer ersetzt den bisherigen Zwei-Layout- Collapse für Kopien. `g1/g2/g3/gn2/gn4large` sowie `ss/sv/vs/vv` mit den Vector-Arbeitsgrenzen werden aus den Originalregeln selektiert. Kernelquellen und Metallib bleiben unverändert; keine neue Flush-/Wait-Grenze. Überwachte GPU-Prüfung: BF16/FP32, alle sieben Operationen, leere Eingaben, Scalar/Vector-Grenzen bei 1/65535/65536/65537, alle Donation-Prioritäten, Column-/General-Layouts, zweiachsiges Broadcasting, rank-5 General-Dispatch, nichtkonstante Reverse-/Offset- und rank-5-Indizierung, gemischte Typen und Integer-Division mit Float-Promotion. Die erste Donation-Prüfung hielt ihre ursprünglichen Eingaben durch Rust-Shadowing ungewollt weiter am Leben; die Testeingaben werden nun vor der Auswertung ausdrücklich freigegeben. Der Backend war in diesem Fall korrekt nicht-donierend. Keine Änderung der Original-Ownership-Regeln zur Anpassung an eine falsche Testannahme. Das bleibt `cfg(test)`-Grapharbeit; vollständige Modell-/Produktintegration und der Gesamtperformance-Nachweis bleiben offen. Prüfstand: **83/83 normal (44,06 s)**, **83/83 unretained (44,03 s)**, binärer Graph mit Fast-Fences **1/1 (0,13 s)**. Release-Test-Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung, Originalquellen-/Metallib-Prüfung bestanden. Prüfbeleg: `local-eval-results/20260907-mtplx-port/graph-binary-check.log`. ### Shared-Expert-MLP als zusammenhängender Graph (2026-09-07) `_FusedGateUpMLP` ist jetzt aus normalen Graphknoten aufgebaut: quantisierte fusionierte Gate/Up-Projektion → Split → der tatsächlich erfasste kompilierte BF16-SiLU-Kernel → separater Multiply → quantisierte Down-Projektion. Kein eager Mehrkernel-Callback und keine neue Shaderimplementierung. Split ist ein gemeinsamer Mehrfach-Output-Knoten mit Geschwistern. Jedes Geschwister trägt denselben Operation-Payload; der bestehende Evaluator kann jedes davon als primären Output wählen. Der schnelle Split übernimmt exakt die Flags-/Data-Größen-Regeln aus `common.cpp`, allgemeine Indizes gehen über die Slice-Fallbackknoten aus `ops.cpp`. Das ist materiell für Submission: bei `[2,6]` entlang der letzten Achse liefert Split pro Hälfte `data_size=6`, nicht die überstrichene Spanne von 9 Elementen. Der neue Graph zählt das referenzgleich; die älteren isolierten Buffer-Helper sind damit nicht pauschal als graph-/scheduling-identisch erklärt. Die SiLU-Graphoperation nutzt die unveränderten 19 erfassten JIT-Varianten. Contiguity, Joint-Collapse, negative/large Indizes, dynamische Ränge und Donation folgen `common/compiled.cpp` und `metal/compiled.cpp`. Insbesondere hat compiled Donation keine 16-KiB-Slack-Grenze; diese wird nicht aus Unary übertragen. Die Kernelwahl liest die Output-Data-Größe wie im Referenzcode vor der Allokation, nicht ersatzweise die logische Shape. Dieser Port betrifft den erfassten nichtskalaren BF16-SiLU-Pfad, nicht einen allgemeinen Compiler. 24 neue modellfreie Receipts wurden direkt durch die tatsächliche MTPLX- Klasse erzeugt: 1/4/7/2048 Zeilen, installierte 2560→1280→640→2560-Projektionen und kleine 128/64-Grenzfälle, 4-/8-Bit und Gruppen 32/64. Alle 24 finalen Outputs sind exakt. Zusätzlich stimmen beide Outputs der zehn vorhandenen SiLU/Gate-Up-Fixtures durch den echten Split-/Multiply-Graphen exakt. Separate Layoutprüfungen decken Split-Geschwisterauswahl, wiederholte und allgemeine Indizes, Strides/Offsets und compiled Donation ab. Positive und negative nichtzusammenhängende Ränge 4/8 decken die festen und dynamischen erfassten SiLU-Kernel ab. Die Donation eines Inputs mit negativer Singleton-Stride übernimmt im strided compiled Zweig die Output-Strides; diese beim abschließenden Source-Abgleich korrigierte Stelle hat einen eigenen Regressionstest. Der Referenzgenerator verwendet den bestehenden Pattern-/QuantizedLinear- Aufbau gemeinsam mit den MoE-Fixtures; kein Download und kein Modellladen. Referenzreceipts: `tests/fixtures/mtplx-shared-mlp.jsonl`. Produktanbindung, übrige Modelloperationen und Gesamtmodell-Performance-Parität bleiben offen. Prüfstand: gesamte Port-Suite **85/85 normal (43,50 s)** und **85/85 unretained (43,79 s)**. Nach der abschließenden Singleton-Stride-Korrektur die beiden betroffenen Tests erneut **2/2 normal (0,28 s)**, **2/2 unretained (0,31 s)** und **2/2 Fast-Fences (0,27 s)**. Clippy, Produkt-Buildcheck, Python-Syntax, Format-/Diff-Prüfung und Originalquellen-/Metallib-Prüfung bestanden. Prüfbeleg: `local-eval-results/20260907-mtplx-port/graph-shared-mlp-check.log`. ### Qwen-Normalisierungsmodule als zusammenhängender Graph (2026-09-07) `normalization.rs` bildet jetzt `GroupedRMSNorm` und `SigmoidRMSNormGated` aus `qwen4_exp.py:350–386` als gewöhnliche Graphknoten ab. Gruppierte Norm: Reshape → ungewichtete RMSNorm → Reshape → voller Gewichts-Multiply. Die Gewichtung wird nicht in RMSNorm gezogen; die BF16-Rundungsstelle bleibt. Gated Norm: gewichtete RMSNorm, Gate-Cast nach FP32 → Sigmoid, Norm-Cast nach FP32 → Multiply mit Gate als erstem Operand → Rückkonvertierung auf den Hidden-State-Typ. Auch ohne Gate erfolgt diese Rückkonvertierung. Keine neuen Shader und kein eager Callback für das gesamte Modul. Alle **25 bestehenden tatsächlichen MTPLX-Modulreceipts** stimmen exakt: zehn Gruppierungs-/Kernelgrenzfälle und fünf Tokenzahlen (1/4/7/11/2048) mit keinem, zusammenhängendem oder gestridetem Projektions-Gate. Projektions- Gates entstehen durch echte Slice-/Reshape-Knoten, nicht vorab dichte Buffers. Zusätzliche Prüfungen sichern gemischte Gewichtstypen, Rückkonvertierung mit/ohne Gate und ungültige Gruppengrößen ab. Prüfstand: gesamte Port-Suite **86/86 (44,38 s)**; beide Normalisierungs- Graphprüfungen zusätzlich **2/2 unretained (0,26 s)** und **2/2 Fast-Fences (0,26 s)**. Clippy, Produkt-Buildcheck und Originalquellen-/Metallib-Prüfung bestanden. Beleg: `local-eval-results/20260907-mtplx-port/graph-norm-check.log`. Der Graph bleibt `cfg(test)`; vollständige Modell-/Produktanbindung und Gesamtmodell-Performance-Parität bleiben offen. Dies ersetzt keinen P16-Lauf. ### GDN-Decode als Zustandsgraph und Dispatch-Geometrie (2026-09-07) `qwen_mtplx/gdn.rs` verbindet die Eingangsprojektionen, den tatsächlichen dreifachen Custom-Kernel-Output und die Ausgangsprojektion als normale Array-Knoten. Fusionierte Projektionen verwenden Split-Geschwister; getrennte und gemischt quantisierte Projektionen bewahren qkv → z/Head-Reshape → b → a. Conv- und FP32-Delta-Zustand werden als Graphwerte an den Folgeschritt gegeben. Ein fehlender Conv-Zustand mit vorhandenem Delta-Zustand entsteht wie in der Referenz als Broadcast-Nullarray, das erst am Custom-Kernel materialisiert wird. Die Custom-Primitive folgt `metal/custom_kernel.cpp`: alle drei Outputs zuerst allokieren, danach nicht-row-contiguous Inputs in Argumentreihenfolge per General-Copy vorbereiten, Offsets/physische Data-Größen binden und Kopien bis zur Command-Completion halten. Kein eager Mehrkernel-Callback und kein neuer Shader. **Konkrete Geometrieabweichung korrigiert:** Der bisherige eager `gdn_decode` übermittelte das MTPLX-Thread-Grid `[256,1,48]` mit `individual_threads=false`. Die native Bridge führte damit `dispatchThreadgroups` aus: 256 Gruppen in X statt einer, bei identischen Ausgaben aus redundanten Schreibvorgängen. `gdn_step_fused.py:237`/`custom_kernel.cpp` verlangen `dispatchThreads`. Der neue Graph und der alte Helper nutzen jetzt dieselbe korrekte Bindung. Das ist eine Korrektur im bislang `cfg(test)`-Port, **keine Erklärung oder Behebung des produktiven UI-Stalls**. Es wurde kein Gesamtmodell-Speedup daraus abgeleitet. Ein opt-in Test-Recorder erfasst erfolgreiche native Dispatch-Aufrufe mit Kernelname, Grid, Gruppengröße und Thread-/Gruppensemantik. Regressionstests prüfen den tatsächlichen GDN-Aufruf im eager und Graph-Pfad, nicht nur Hashes. Der Recorder ist `cfg(test)` und gelangt nicht in Produktmessungen. Zwölf bestehende tatsächliche `GatedDeltaNet.__call__`-Receipts stimmen exakt: fused/separate/mixed, mit/ohne anfänglichen Conv-Zustand, jeweils zwei Schritte. Jeder Fall läuft sowohl mit Evaluation pro Schritt als auch als ein verbundener Graph mit gemeinsamer späterer Evaluation. Zwei weitere GDN-Kernelreceipts prüfen gestridete Inputs mit Offset, General-Copies und Evaluation vom letzten Output-Geschwister aus. Wiederverwendung des MLP-Affine-Fixture-Helfers; keine neuen Referenzdaten, Modelle oder Downloads erforderlich. Prüfstand: Port-Suite **88/88 normal (43,96 s)**; nach dem abschließenden z-Reshape-Reihenfolgeabgleich **88/88 unretained (44,01 s)** und betroffene Graphprüfungen **2/2 normal (0,18 s)** / **2/2 Fast-Fences (0,18 s)**. Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung und Originalquellen-/Metallib-Prüfung bestanden. Beleg: `local-eval-results/20260907-mtplx-port/graph-gdn-check.log`. Staged Prefill/Verify, Branch-/Capture-/Cache-Orchestrierung und vollständige Modell-/Produktanbindung bleiben offen; P06 und die P16-Paritätsabnahme bleiben unerledigt. Die neue Funktion ersetzt ausdrücklich nicht deren übrige Zweige. ### GDN-Verify, Delta-Update und gemeinsame Compiled-Ausführung (2026-09-07) Der fusionierte Conv-Verify-Zweig für B=1/S=2..6 ist jetzt durchgehend als Array-Graph verbunden: Eingangsprojektionen/Split → Conv/Norm → Delta-Update → SigmoidRMSNormGated → Ausgangsprojektion. Conv-/Delta-Zustand und die sechs Capture-Commit-Eingänge werden referenzgleich weitergegeben. Capture hält qkv/q/k/v/a/b nur bei aktivierter Erfassung; ohne Capture werden diese zusätzlichen Referenzen nicht im Rückgabewert gehalten. Cache-Advance und Modell-Branchauswahl bleiben Aufgaben der noch ausstehenden Orchestrierung. `gated_delta_update` enthält normale Sigmoid-, Compiled-compute_g- und Custom-Kernel-Knoten einschließlich optionalem FP32-Nullzustand und Maske. Die ursprünglichen Conv/Norm- und Rekurrenzkernel verwenden gemeinsam die CustomKernel-Allokations-/Copy-/Lebensdauerfolge des vorigen Decode-Ports. Der GDN-Conv-Dispatch zählt 10240 Threads/1024 pro Gruppe; Delta zählt `[32,128,B*48]` Threads mit `[32,4,1]` pro Gruppe. Die Testbeobachtung an der nativen Grenze sichert diese Geometrien ab. SiLU und compute_g verwenden den gemeinsamen `compiled.rs`-Evaluator für die bereits erfassten nichtskalaren Kernel: Contiguity über alle Eingänge, Broadcast-/Joint-Collapse, negative/large Indizes, Output-Allokation und Donation gemäß `common/compiled.cpp`/`metal/compiled.cpp`. Kein neuer Shader und kein allgemeiner JIT-Ersatz. Ein direkter DOT-Export aus dem gepinnten Referenzprozess bestätigt A_log `[48]`, a `[1,1,48]` und dt_bias `[48]` als direkte Compiled-Eingänge; die Softplus-Konstante ist im erfassten Shader. Auch die einzelne GDN-Zeile wählt deshalb den kollabierten strided-1-Kernel, nicht anhand der physischen Länge einen contiguous-Kernel. Die tatsächliche compute_g-Kernelwahl wird für alle 80 Delta-Receipts mitgeprüft. Nachweise: sechs Conv/Norm-Kernelreceipts und 80 tatsächliche Delta-Update- Receipts exakt (1/4/7/32/2048 Zeilen, beide Gate-Layouts, Maske an/aus, Initialzustand an/aus, zwei fortgesetzte Schritte). Zwölf vollständige echte Verify-Modulreceipts bei 2/4/6 Zeilen stimmen einschließlich Q/K/V exakt; alle drei Hauptoutputs ohne Capture sind dazu bytegleich. Der erste Verify-Testversuch verwendete für vier Zeilen einen nicht existierenden Forward-Fixturenamen; die Zuordnung wurde auf die vorhandenen vollständigen Staged-Receipts korrigiert, keine Referenzwerte oder Hashprüfung abgeschwächt. Prüfstand: gesamte Port-Suite **90/90 normal (46,46 s)** und **90/90 unretained (45,17 s)**. Fast-Fences: GDN **4/4 (1,13 s)**, MLP **2/2 (0,28 s)**. Nach zusätzlicher compute_g-Dispatch-Assertion derselbe betroffene Test erneut normal/unretained/Fast-Fences bestanden (0,94/0,90/0,96 s). Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung und Originalquellen-/Metallib-Prüfung bestanden. Beleg: `local-eval-results/20260907-mtplx-port/graph-gdn-verify-check.log`. Offen bleiben der allgemeine Concatenate/Conv1d/Reduktions-Prefill-Graph, maskierte/ragged Conv-Fallbacks, Single-Row-Output-Fusion als Graph, vollständige Branch-/Capture-Commit-/Cache-Orchestrierung und Produktintegration. Die 2048-Zeilen-Rekurrenzprüfung ist **kein vollständiger Prefill-Nachweis**. P06/P16 und das Drei-Modell-Performanceziel bleiben ausdrücklich offen. ### GDN-Conv1d-Prefill als zusammenhängender Array-Graph (2026-09-07) Der unmaskierte, längenlose Conv1d-Fallback ist jetzt von den Eingangsprojektionen bis zur Ausgangsprojektion verbunden: Concatenate → Contiguous-Conv-Zustand → Depthwise-Conv1d → erfasste SiLU → Split/Head-Reshape → FP32-L2-Summe/Rsqrt → BF16-Rückkonvertierung/Q-Skalierung → Delta-Update → SigmoidRMSNormGated → Ausgangsprojektion. Auch S=1 bei abgeschalteter Fusion nimmt diesen Pfad. Die vorherige Beschränkung auf den fusionierten Verify-Zweig entfällt damit für unmaskierte Eingaben ohne Cache-Längen. Modellwahl und cache.advance(S) sind weiterhin nicht durch diese Graphfunktion ersetzt. Concatenate verwendet die gemeinsame Copy-Implementierung jetzt auch als GeneralGeneral: gemeinsame Kollabierung von Quell-/Ziel-Strides, echte Byte-Offsets, Referenz-Datengrößen und concurrent disjoint writers. Die Output-Slices sind wie in der Referenz primitive-/speicherlose temporäre Array-Deskriptoren mit anschließend geteiltem Output-Backing. Conv1d allokiert zuerst den Output und materialisiert danach bei Bedarf Input und Gewicht in dieser Reihenfolge. Kein neuer Shader und keine eigene Faltung: Der originale `depthwise_conv_1d_*`-Kernel zählt `[C,Tout,B]` Threads. Die GDN-Summe wählt referenzgleich zwischen row_reduce_looped (16 Köpfe bei S=1) und row_reduce_simple (ab 32 Köpfen); die übrigen allgemeinen Reduktionspläne werden nicht als portiert ausgegeben. Der bestehende vollständige Modulreceipt-Test umfasst jetzt **52 Fälle**: 12 fusionierte Verify-Fälle und 40 Conv1d-Fallback-Fälle, S=1/2/4/6/7/32/2048, Initialzustand an/aus, zwei fortgesetzte Schritte und die jeweils anwendbaren Fusionsflags. Alle sechs Output-Hashes einschließlich q/k/v sowie beider Folgezustände sind exakt. Ohne Capture stimmen die drei Hauptoutputs bytegenau mit dem Capture-Lauf überein. Kernelwahl und Dispatch-Geometrie von Conv1d und beiden Summen werden an der nativen Grenze zusätzlich geprüft. Der strided V-Capture wird ausschließlich nach dem eigentlichen Forward für den Fixture-Reader gepackt; der Modellgraph behält seinen originalen View. Ein kleiner zusätzlicher Concatenate-Test prüft vierdimensionale transponierte und rückwärts gerichtete Views, alle vier Achsen, Typ-Promotion, leere Inputs und die Referenz-Single-Input-Identität vor Achsenvalidierung. Prüfstand: komplette Port-Suite **91/91 normal (45,89 s)** und **91/91 unretained (45,40 s)**; Fast-Fences: GDN **4/4 (1,84 s)**, Concatenate **1/1 (0,05 s)**. Clippy, Produkt-Buildcheck, Format-/Diff-Prüfung bestanden. Originalquellen weiterhin 15 Körper / 35 Custom-Einstiegspunkte / 20 Runtime-Einheiten / 84 Runtime- Einstiegspunkte plus dynamische QSA-Quellen exakt, unveränderte Metallib-SHA256 `dc59d1cceb1a5c7e578232e6e41e28e2c73c9463ac6dbc3886c3ee17ffc270ed`. Prüfbeleg: `local-eval-results/20260907-mtplx-port/graph-gdn-prefill-check.log`. **Weiter offen:** maskierter Conv-Select, ragged Cache-Längen/Gather, Single-Row-Output-Fusion als Graph, vollständige Modell-/Cache-/Capture-Commit- Orchestrierung und Produktintegration. P06/P16 bleiben offen. Der gesamte Port ist weiterhin `cfg(test)`; weder UI-Responsivität noch Durchsatzparität sind damit nachgewiesen. Die vollständigen Drei-Modell-Chats werden dadurch nicht ersetzt; es gab keinen Modelllauf, Download oder Performance-Rollback. ### Maskierter und längenabhängiger GDN-Prefill (2026-09-07) Der Conv1d-Graph enthält nun auch MTPLXs Maskierungs- und ragged-State-Zweig. QKV wird vor Concatenate mit `where(mask[..., None], qkv, 0)` maskiert; Capture bewahrt genau diesen QKV-Strom. Die ursprüngliche Maske geht zusätzlich an die Delta-Rekurrenz. Für Cache-Längen bleibt die Referenzfolge als einzelne Knoten erhalten: Maximum/Minimum auf `[0,S]` → ExpandDims → Arange(INT32) → Add → ExpandDims → GatherAxis über das Conv-Fenster. Keine CPU-Auswertung des Längentensors und kein vorgezogener GPU-Sync. Ohne Längen bleibt der bestehende Contiguous-Tail-Zweig unverändert. `indexing.rs` enthält die dazu verwendeten Select-, GatherAxis- und Prefix- Arange-Primitiven. Select übernimmt Typ-/Broadcast-Regeln sowie Scalar-/Vector-/ General-Kernelwahl, Donation, Strides und Dispatch aus der gepinnten Runtime. Gather verwendet die bereits exportierten BF16/I32- bzw. BF16/U32-Kernel mit tatsächlichen Src-/Index-Contiguity-Flags, Größen, Strides und Byte-Offsets. Statisches Broadcast wird von Binary, Select und GatherAxis gemeinsam genutzt. Andere Gather-Dtypes bzw. dynamisches Broadcast-Tracing werden damit nicht als portiert erklärt. Eine ABI-Abweichung wurde an der gemeinsamen Bridge behoben: Leere Inline- Vektoren werden von `ds4_gpu_mtplx_encode` nicht mehr pauschal zurückgewiesen. Die Referenz bindet bei Rank-1-Gather tatsächlich null Byte für Shape/Strides. Die Bridge führt jetzt denselben Metal-Aufruf aus; kein Dummy-Payload, keine Shaderänderung. Nichtleere Nullpointer, Übergröße, Offsets und doppelte Slots werden weiterhin zurückgewiesen. Der Rank-1-Gather-Test schließt rückwärts gerichtete Source-/Index-Views mit nichtnull Byte-Offsets ein. Der erweiterte vollständige GDN-Modultest prüft **116 MTPLX-Receipts exakt**, jeweils sechs Outputs einschließlich beider Zustände, plus bytegleiche Capture-off-Hauptoutputs. S=1/2/4/6/7/32/2048, maskiert/unmaskiert, zwei fortgesetzte Schritte, Initialzustand an/aus und Längen unter/innerhalb/über der Chunk-Grenze. Längenfälle hier S=4/7; S=1 bei aktivierter Output-Fusion bleibt bis zum Port dieser Fusion offen. Die tatsächliche Select-/Gather-Kernelwahl und Geometrie werden zusätzlich beobachtet. Ein kleiner Indexing-Test deckt alle fünf Select-Layoutarten, Column-Layout, Broadcast-Gather, negative Indizes, BF16/I32/U32, Rank-1-Leerargumente und leeres Arange ab. Prüfstand: gesamte Port-Suite **92/92 normal (45,39 s)** und **92/92 unretained (45,23 s)**. Fast-Fences: GDN **4/4 (2,62 s)**, Indexing **1/1 (0,06 s)**. Clippy (8,87 s), Produkt-Buildcheck (3,26 s), Format-/Diff- und Originalquellen-/ Metallib-Prüfung bestanden. Prüfbeleg: `local-eval-results/20260907-mtplx-port/graph-gdn-masked-lengths-check.log`. Weiterhin offen sind Single-Row-Output-Fusion, vollständige Modell-/Cache-/ Capture-Commit-Orchestrierung und Produktintegration. Der Port bleibt `cfg(test)`; keine Modell-/UI-/Performance-Paritätsbehauptung. P06/P16 und das vollständige Drei-Modell-Ziel bleiben offen; keine Downloads oder Rücknahmen. ### Gemeinsamer GDN-Forward, Output-Fusion und Cache-Fortschreibung (2026-09-07) Die getrennten kanonischen `fused_decode`-, `prefill`- und `fused_verify`- Einstiege sind durch `gdn::forward` ersetzt. Dieser bildet für die installierte Inferenzgeometrie die Reihenfolge von `GatedDeltaNet.__call__` ab: Projektionen, Conv-State/Maskierung, Fused-Step oder Conv-Zweig, Capture, Delta-Update, Cache-Fortschreibung und Output-Fusion oder Norm/Projektion. Die unveränderten Kernel werden nicht anhand lokaler Geschwindigkeitsvergleiche ausgewählt. - Capture sperrt den Live-Step, aber nicht pauschal Conv-/Output-Fusion. Bereits gespeicherte Capture-Arrays bleiben erhalten, bis ein neuer Capture- Aufruf sie ersetzt. Der Step-Zweig kehrt vor der separaten Output-Fusion zurück. - Cache-Längen und Masken sperren Conv-Fusion; B>1 und fehlender Cache verwenden den allgemeinen Conv-Zweig. Ohne Cache wird kein Cache-Tail-Graph erzeugt. Die tatsächlichen einmaligen Single-/Multi-Row-Geräteproben werden wie in MTPLX ausgeführt und ihr Erfolg pro Prozess gespeichert. - `Cache::advance` subtrahiert S von Längen und linkem Padding als Tensor- Operationen, bevor der Output-Graph aufgebaut wird; kein CPU-Readback. Der aktuelle Vertrag für diese Metadaten ist INT32. - Die Single-Row-Output-Fusion verwendet die Originalkörper für Gruppen32/64 und BF16/FP32-Eingabe, einschließlich exakt 81920 Threads in 1024er Gruppen. Referenzabdeckung: alle **264 Forward-Receipts** mit fusionierten, getrennten und gemischt quantisierten Eingangsprojektionen; jeweils sofortige und verzögerte Auswertung zweier aufeinanderfolgender Aufrufe. Zusätzlich werden die tatsächlich ausgeführten Step-/Conv-Fusionszweige gegen die Referenzdaten geprüft. Alle **130 Staged-Receipts** sind nun eingeschlossen, auch die zuvor fehlenden Single-Row-Fälle mit Output-Fusion. Vier direkte Output-Kernel- Receipts sichern Typen, Gruppen und Dispatch-Geometrie ab. `tools/mtplx-kernel-fixtures.py:gdn_graph_lifecycle_fixtures` erzeugt außerdem **24 neue tatsächliche MTPLX-Modulreceipts**, nicht Rust-generierte Sollwerte: B=1/2, S=1/7, kein Cache/leerer Cache/Metadaten, jeweils zwei Aufrufe mit Capture nur beim ersten. Sie prüfen Ausgaben, Conv-/Delta-Zustände, Längen/Padding und den Erhalt der Capture-Array-Identitäten beim Folgeaufruf. Verifikation: vollständige Port-Suite **92/92 (48,75 s)**, mit unretained Command Buffers **92/92 (48,96 s)**; GDN mit Fast-Fences **4/4 (5,46 s)**. Release-Clippy, Produkt-Check, Format-/Diff-Check und unveränderter Referenz-Shaderexport bestehen. Der Prüfbeleg liegt unter `local-eval-results/20260907-mtplx-port/graph-gdn-forward-check.log`. Weiter offen: äußerer Modellablauf mit Maskenerzeugung, Cache-Batchoperationen, Capture-Commit/Repair, weitere Graphkomponenten und Produktintegration. Der kanonische Graph bleibt `cfg(test)`. Diese Modulprüfungen sind weder eine UI-Responsivitätsmessung noch ein Nachweis der Modell-/Performance-Parität; P06/P16 und das Drei-Modell-Ziel bleiben offen. ### GDN-Capture-Commit mit nachfolgendem Decode (2026-09-07) `gdn::Cache` übernimmt jetzt die Validierungsregeln und den reinen GDN-Zweig von `Qwen4ExpTextModel.commit_verified_window`: validierte Capture-Zeilen auf die angenommene Länge beschränken, Delta-Rekurrenz vom Snapshot ausführen, Conv-Tape aus Snapshot und behaltenem QKV bilden, Capture freigeben. Fehlender Conv-Snapshot wird wie in MTPLX durch einen Nullzustand ersetzt; Delta-Snapshot und passende Capture-Breite sind verpflichtend. Längen/Padding werden dabei weder zurückgesetzt noch fortgeschrieben. Die Trennung zwischen Validierung und Replay erlaubt dem noch zu verbindenden äußeren Modellablauf, zuerst **alle** Schichten zu validieren und erst danach irgendeinen Cache zu verändern. Sie ersetzt diese globale Transaktion nicht. QSA-Trim, PLE-Replay und die übergeordnete Fehler-/Rollback-Orchestrierung bleiben ausdrücklich offen. Kein vollständiger P12-Abschluss. **26 neue tatsächliche MTPLX-Commit-Receipts** decken Fenster1/2/4/6, jede behaltene Präfixlänge und vorhandene/fehlende Conv-Snapshots ab. Die sieben Ausgabehashes einschließlich des nachfolgenden Decode stimmen exakt; im Rust- Graph sowohl bei sofortiger als auch verzögerter Commit-Auswertung. Native Dispatch-Aufzeichnung prüft: keine Submission während der Commit-Konstruktion, nur eine Delta-Rekurrenz und keine Projektionen/Conv-Kernel im isolierten Replay. Ungültige Präfixe, fehlende/kurze Snapshots und fehlende/falsch breite Captures werden ohne Veränderung der Cache-Array-Identitäten geprüft. Ein zunächst abweichender Metadatenhash lag am Ablesezeitpunkt des Tests: Pythons `mx.array.__isub__` überschreibt den Deskriptor des gespeicherten Metadatenobjekts beim folgenden Decode. Der Rust-Test liest deshalb die dann aktuellen Cache-Metadaten statt einer vorher angelegten Wertkopie. Die echten MTPLX-Receipts wurden nicht geändert; der Commit selbst erhält die Metadaten. Verifikation: Port-Suite **92/92 (49,60 s)**, unretained **92/92 (49,50 s)**; GDN mit Fast-Fences **4/4 (5,90 s)**. Release-Clippy, Format-/Diff-Check und unveränderter Shaderexport bestehen. Prüfbeleg: `local-eval-results/20260907-mtplx-port/graph-gdn-commit-check.log`. Der kanonische Port ist weiterhin ausschließlich `cfg(test)`; keine Aussage über Produktperformance, UI-Responsivität oder die 2%-Abnahme. ### Hyper-Connection-Graph und Original-Quantisierung (2026-09-07) Der kanonische Graph verbindet jetzt die Custom-Primitiven von `hyper_connection.py` und `hyper_connection_v3.py` mit der originalen `prepare_v3_pack`-Kette: Down/Inject konkatenieren, beide Matrizen mittels `fast::Quantize` quantisieren, sechs Contiguous-Ausgänge auswerten. Die V3- Geräteprobe führt beide echten Kernel mit den originalen Dummy-Geometrien aus und speichert ihr Ergebnis pro Prozess. Die Probe bleibt vor der kostenpflichtigen Pack-Vorbereitung dem noch zu verbindenden Modellselektor zugeordnet. `linear::quantize` übernimmt Shape-/Parameterprüfung, drei Array-Siblings, Allokationsfolge und Row-Contiguous-Kopie aus dem gepinnten Runtime-Backend. Es bindet die unveränderten `affine_quantize_*`-Kernel aus derselben Metallib: Gruppen32/64/128, Bits2/3/4/5/6/8, BF16/F16/F32. Die allgemeinen Elementkernel- Typnamen sind hier nicht gültig; die originalen affinen Symboltypen lauten `bfloat16_t`, `float16_t` und `float`. Diese Bindungsabweichung wurde bei der ersten Ausführung erkannt und korrigiert, ohne Shaderänderung. **59 tatsächliche Quantisierungsreceipts** decken alle 54 Typ-/Gruppen-/Bit- Kombinationen sowie Slice, Transpose und Null-/Positiv-/Negativkonstanten ab. U32-Packs werden roh gehasht, nicht verlustbehaftet nach Float konvertiert. Der echte V3-Pack stimmt in allen sechs Ausgängen exakt mit MTPLX überein; anschließende V3-Leseschritte stimmen sowohl mit neuen als auch bisherigen Sollwerten überein. Die ursprünglichen Read-Kernel mit/ohne Injection bei S=1/4/8 sind ebenfalls über den Graphen geprüft. R1/R2 verwenden genau ihre 11264/81920 Threads, jeweils 1024 pro Gruppe, und zusammen einen Command Buffer. Der frühere direkte V3-Test mit `kernel_qwen_quantize_hyper_q8` ist entfernt; seine Ausgabereferenz und One-Command-Buffer-Prüfung liegen jetzt im verbundenen Test mit Originalquantisierung. Der letztere prüft den Zähler des tatsächlichen Graph-Streams, nicht den globalen Zähler der alten Produktqueue. Zu diesem Zwischenstand noch offen für `GatedResidual`: eager Norm/Matmul/Mean- Kette, Modellselektion und Lebensdauer des pro Modul gecachten Packs sowie Verbindung mit dem restlichen Modell und Produktpfad. Keine Rücknahme wegen Mikrobenchmark-Ergebnissen; `cfg(test)`, P09/P16 und Gesamtparität bleiben offen. Verifikation: vollständige Port-Suite **94/94 (51,84 s)**, unretained **94/94 (51,14 s)**. Fast-Fences: Hyper **1/1 (0,09 s)**, Quantize **1/1 (0,26 s)**. Release-Clippy, Format-/Diff-Check und unveränderter Shaderexport bestehen. Prüfbeleg: `local-eval-results/20260907-mtplx-port/graph-hyper-quantize-check.log`. ### Verbundener GatedResidual einschließlich eager Prefill (2026-09-07) `hyper::GatedResidual` verbindet jetzt für die installierte BF16-Geometrie den vollständigen Read: GroupedRMSNorm, Down/4, SiLU, Up/Sigmoid, gruppiertes Produkt und Mean sowie die optionale Injection. Mean bleibt wie im Original eine BF16-Summe mit anschließender BF16-Multiplikation mit1/4. Die dense Projektion verwendet die unveränderte Runtime-Metallib mit originaler M5-Max-Auswahl: GEMV, Wide-GEMV bis15 Zeilen, NAX-GEMM und NAX-Split-K samt FP32-Zwischenergebnis und BF16-Akkumulationsausgang. Statisches Flatten/Unflatten, Transpose-/Kopierprüfung, Function Constants, Bindings und Dispatch-Geometrie folgen `ops.cpp`, `matmul.cpp` und `reduce.cpp` der gepinnten Runtime. Der Modellselektor prüft zuerst V3 (eine Zeile, Combine, nichtquantisierter Down, Geräteprobe), anschließend den ursprünglichen fusionierten Read (bis8 Zeilen), ansonsten eager. Der V3-Pack gehört zur Modulinstanz, wird nur einmal erzeugt und über spätere Fused-/Eager-Aufrufe hinweg erhalten. Der Combine-Ausgang behält die ursprüngliche Hyper-Array-Identität. Quantisierte HC-Projektionen bleiben entsprechend MTPLX auf der eager-Kette. `hyper_forward_fixtures` ruft die tatsächliche MTPLX-Klasse auf, ohne sie nachzuimplementieren. Alle **128 Fälle** stimmen exakt überein: dichte und quantisierte Gewichte, mit/ohne Combine, S=1/2/4/8/15/16/32/2048 und alle vier Kombinationen der beiden HC-Schalter. Geprüft sind beide Ausgänge, ausgewählter Pfad (111 eager,15 fused,2 V3), Pack-Existenz/-Identität und die native NAX-/Split-K-Auswahl. Keine Referenzwerte wurden an Rust-Ergebnisse angepasst. Die Operatoren sind weiterhin nur Teil des kanonischen `cfg(test)`-Ports. DecoderLayer/PLE, vollständige Modell- und Produktanbindung sowie P09/P16- Gesamtabnahme bleiben offen. Die Beschränkung des dichten Wrappers auf die installierten BF16-Projektionen ist kein Nachweis für beliebige Datentypen, Dot-Produkte, leere Matrizen oder andere GPU-Architekturen. Es gab keine Shaderänderung, kleinere Prefill-Chunks oder Rücknahme nach Mikrobenchmarks. Verifikation: gesamte Port-Suite **95/95 (55,49 s)**, unretained **95/95 (52,73 s)**, Hyper mit Fast-Fences **2/2 (0,94 s)**. Release-Clippy, Format-/Diff-Check und unveränderter Shaderexport bestehen. Prüfbeleg: `local-eval-results/20260907-mtplx-port/graph-hyper-forward-check.log`. ### PLE-Projektion und dilatierte Cache-Fortsetzung (2026-09-07) Der kanonische Graph verbindet `PLELayer` ab dem Ergebnis von `NGramEmbedding`: Embedding-Cast, Key-/Value-Projektionen, drei GroupedRMSNorms, BF16-Produktsumme, Divisor/Signed-Sqrt-Gate, Sigmoid, Broadcast/Reshape und Short-Conv mit anschließendem SiLU und Residual-Add. Vorhandene dichte und quantisierte Projektionen sowie Graph-/Copy-/Norm-/SiLU-Operatoren werden wiederverwendet. Abs/Sign folgen dem originalen Typvertrag. Die gemeinsame Row-Sum-Auswertung erhält GDNs FP32x128-Route und ergänzt PLEs BF16x2560-Route mit640 Threads und originaler Simple-/Looped-Grenze. Die PLE-Faltung mit Kernel4/Dilatation3 ist **nicht** der GDN-Depthwise1D-Pfad. Die gepinnte Runtime bettet sie in2D ein und verwendet `implicit_gemm_conv_2d_bfloat16_bm32_bn8_bk16_wm4_wn1_channel_1_filter_l`. Rust bindet diesen unveränderten Metallib-Kernel mit den originalen Conv-/GEMM- Parametern und der Grid-Geometrie. Ausgabeallokation sowie Input-/Weight-Kopien verwenden denselben vorhandenen Helper wie GDN, in Originalreihenfolge. Der Cache speichert die letzten9 Zeilen des Fensters als lazy Slice; die Faltung liest noch das ganze Fenster, bevor der letzteS-Abschnitt aktiviert wird. **84 tatsächliche MTPLX-PLELayer-Receipts** prüfen dense/quantized, S=1/4/7/8/ 32/2048 sowie Batch2/S7; kein, leerer oder12-zeiliger Vorzustand, jeweils mit anschließendem Ein-Zeilen-Decode. Der zweite Embedding-Eingang ist FP32 und wird wie im Modell auf BF16 gecastet. Ausgabe und Cache stimmen exakt überein, sowohl bei unmittelbarer als auch gemeinsamer verzögerter Auswertung (168 Vergleiche). Native Faltungsauswahl/-Geometrie ist zusätzlich geprüft. Der Fixture-Provider ersetzt ausschließlich den Lookup-Eingang; der restliche Aufruf ist die tatsächliche unveränderte MTPLX-Klasse. **Dies beweist keinen N-Gram-Lookup, kein Staging und keine IO-/LRU-Parität.** Noch offen: NGramEmbedding samt Graph- und Staging-Pfaden, Sidecar/Resident- Auswahl, Dequantisierung und Hot-Cache-Vertrag sowie Decoder-/Modell-/Produkt- Anbindung. Der bisherige Produkt-PleReader arbeitet noch anders als MTPLX (u.a. erste-Auftritts-Deduplizierung statt sortierter Unique-IDs und fehlender identischer4096-Unique-Row-Bypass). Er wird nicht durch diese PLE-Projektions- Tests freigestellt. `cfg(test)`, P10/P16 und das Drei-Modell-Ziel bleiben offen. Verifikation: gesamte Port-Suite **96/96 (51,40 s)**, unretained **96/96 (51,07 s)**, PLE mit Fast-Fences **1/1 (1,48 s)**. Release-Clippy, Format-/Diff-Check und unveränderter Shaderexport bestehen. Prüfbeleg: `local-eval-results/20260907-mtplx-port/graph-ple-projection-check.log`. ### N-Gram-CPU-Staging-Hash und rohe History (2026-09-07) `ngram::HashContract::rows` übernimmt den materialisierten CPU-Hash aus `NGramEmbedding._rows_np` für den installierten Vertrag mit3-Grams/16 Heads. Int64-Multiplikation, XOR, positiver Rest und Offsetaddition erhalten das Overflow-Verhalten der NumPy-Referenz. EOS beeinflusst die verschobenen Tokens erst **nach** dem Hash der EOS-Position; der zurückgegebene History-Cache behält die tatsächlichen letzten2 Tokens. Eine EOS-normalisierte History ist nicht die Cache-Repräsentation der Referenz. Der bisherige Produkt-Einzel-Token-Hash bleibt davon getrennt; daraus allein wird kein Unterschied seiner fertigen Row-IDs oder eine Ursache der UI-Verzögerungen behauptet. **64 Original-Receipts** verwenden die installierte EOS-ID248044 und die Originalkonstanten. B=1/2, S=0/1/4/2048, vorherige History-Längen0/1/2/5 und jeweils ein Fortsetzungstoken stimmen in Roh-I64-Ausgabehashes und Shapes exakt überein. Fälle enthalten aufeinanderfolgende EOS, negative Werte und Int64- Grenzwerte. Auch die Python-Slice-Semantik bei S=0 (alle History-Rows) bleibt erhalten. Eingabe-/History-Formen und positive Head-Größen werden geprüft. Rust benötigt keine NumPy-Zwischenmatrizen; die gleiche Berechnung läuft in einem Durchgang, ohne eine GPU-Auswertung oder Synchronisierung einzuführen. Dies ist ausschließlich der CPU-Hash-Baustein, **noch kein verbundenes `NGramEmbedding.stage`/`__call__`**. Lazy GPU-Hash, Stage-Auswahl/-Verifikation, Sidecar/Resident-Gather, Dequantisierung und LRU/Bypass bleiben offen; der pipelined-AR-Pfad wird nicht durch diesen CPU-Baustein ersetzt. P10/P16, Produktintegration und Drei-Modell-Performanceabnahme bleiben offen. Verifikation: CPU-Port-Suite **22 bestanden,75 GPU-Tests explizit ignoriert**; Release-Clippy, Format-/Diff-Check bestehen. Keine neue GPU-Performanceprüfung für diesen CPU-only-Baustein. Prüfbeleg: `local-eval-results/20260907-mtplx-port/ngram-cpu-hash-check.log`. ### Lazy N-Gram-GPU-Hash bis zu den Tabellen-IDs (2026-09-07) `ngram::GpuHash::rows` bildet nun die originale `_graph_path`-Kette bis zum Tabellenaufruf nach: I64-Cast, History-Concat/-Slice, beide voneinander getrennten `_shift_ignore_eos`-Graphen mit Arange/Select/Cummax/Gather, Int64-Multiply/XOR/Remainder und Head-Offsets. Checkpointkonstanten bleiben Array-Leaves. Der Konstruktor liest keine Tokenwerte zurück und wertet keine GPU-Knoten aus; auch eine noch nicht ausgewertete History kann weitergereicht werden. Kein fusionierter Eigenbau-Hash und kein Ersatz durch den CPU-Hash. Gemeinsame Graphoperatoren wurden um Equal/GreaterEqual mit Bool-Ausgang, BitwiseAnd/Xor und Remainder sowie I64-Arange/-Gather und inclusive Cummax erweitert. Für Gather sind8 zusätzliche I64/I64-Spezialisierungen des **unveränderten** Originaltemplates exportiert; der Original-Metallib-Hash ist unverändert. Scan übernimmt seine eigene Allokations-/Donation-Regel ohne die16KiB-Grenze des Unary-Helfers; diese Besonderheit wurde beim Quellabgleich korrigiert und mit einem oversized backing separat geprüft. **60 tatsächliche MTPLX-GPU-Receipts** stimmen in IDs, roher History und Shapes exakt überein: B1/2, S1/4/2048, fehlende oder0/1/2/5-zeilige History und je ein Decode-Folgeschritt. Sofortige und verzögerte Auswertung ergeben120 Vergleiche; der Graphaufbau dispatcht nichts, beide Original-Scans und I64-Gather werden tatsächlich ausgeführt. Zusätzliche30 Scan-Prüfungen decken row-/column-major, Broadcast-Kopien, erhaltene Aliase und Threadgrößengrenzen bis4097 Elemente ab. Ein passender Folgeschritt prüft außerdem lazy I32→I64-Tokens. Die Referenz ruft `_graph_path` selbst auf; ausschließlich der Tabellenaufruf gibt im Fixture seine IDs zurück. Lookup/Dequantisierung, Sidecar/Resident- Wahl, Stage-Auswahl/-Verifikation/-Konsum, Hot-Cache/Bypass und Decoder-/Modell- Anbindung bleiben offen. Kein Nachweis für beliebige leere Cummax-Eingaben, kein vollständiger NGramEmbedding-Aufruf, keine Produkt- oder2%-Abnahme. Verifikation nach der Scan-Donation-Korrektur: reguläre Port-Suite **98/98** in51,93s, Unretained-Command-Buffer-Suite **98/98** in52,73s und der NGram-Test mit `MLX_METAL_FAST_SYNCH=1` **1/1** in0,14s. Release-Clippy sowie Format-/Diff- und Originalquellen-Prüfung bestehen. Diese Zeiten sind Testlaufzeiten, keine Modell-Performancewerte. Prüfbeleg: `local-eval-results/20260907-mtplx-port/ngram-gpu-hash-check.log`. ### Verbundener residenter N-Gram-Graph (2026-09-07) `GpuHash::embedding` verbindet nun den originalen Hash mit `ResidentTable::gather`, affiner Dequantisierung und Head-Reshape. Der residente Pfad liest keine IDs auf die CPU zurück und fügt keine Auswertung hinzu. Der Loader muss die Tabelle vorab materialisieren; Laden/Residency-Entscheidung, Sidecar-I/O, Hot-Cache, Stage-Auswahl und Produktanbindung sind noch nicht portiert. `indexing::take_rows` verwendet wie die Referenz Gather plus Squeeze. Bei zusammenhängenden Tabellen und Indizes läuft der originale GatherFront; andere Views verwenden den originalen allgemeinen Gather, ohne vorgeschaltete Kopie. I64-Indizes, negative Indizes, rank0..4, BF16/F16/F32/U32, Byte-Offsets und die große Indexvariante sind im Dispatch berücksichtigt. Die neue GPU-Dequantisierung übernimmt Output-Allokation vor den drei Contiguous-Vorbereitungen, Bindings und Grid/Thread-Geometrie. Quantize verwendet denselben vorhandenen Copy-Mechanismus. Die Tabelle verwendet gleiche Floating-Dtypes für Scales/Biases; gemischte Parameter-Dtypes und nicht-affine Quantisierung werden hier nicht beansprucht. Originalquellen unverändert: 12 weitere GatherFront-Spezialisierungen sowie40 originale Gather-JIT-Wrapper, ausschließlich mit angepassten Einstiegspunktnamen. Zwei zusätzliche geprüfte Runtime-Units; Export insgesamt15 Custom-Bodies, 35 Custom-Einstiege und22 Runtime-Units/144 Runtime-Einstiege. Der unveränderte Original-Metallib-Hash bleibt `dc59d1cceb1a5c7e578232e6e41e28e2c73c9463ac6dbc3886c3ee17ffc270ed`. Ein erster Compile-Versuch fand die falsche Reihenfolge der Gather-Abhängigkeiten; behoben durch Platzierung nach dem Original-Utils-Export, ohne Kerneländerung. Neue Original-Receipts, jeweils unmittelbar und verzögert exakt verglichen: - 324 affine Dequantisierungen: BF16/F16/F32, group32/64/128, bits2/3/4/5/6/8, plain/transpose/slice/offset/broadcast/batch. - 162 tatsächliche `NGramTable._lazy_gather`-Aufrufe: BF16/F16, raw8/9/160 und Q4x160, zusammenhängende/transpose/offset Tabellen, skalare bis4D IDs, Slice- und Broadcast-ID-Views. GatherFront/Gather-Auswahl wird geprüft. - 24 vollständige originale residente `_graph_path`-Ausgaben einschließlich Decode-Folgeschritt: raw/Q4, B1/2, S1/4/2048. Tabelle bewusst klein (17 Zeilen), echte Headbreite160 und Ausgang2560; Hashkonstanten für kleine Vokabelgrößen angepasst. Kein Ersatz des Tabellenaufrufs. Embedding und rohe History stimmen exakt überein, auch wenn beide Schritte vor der Auswertung aufgebaut werden. Das sind Korrektheits-/Graphbelege, keine Vollmodell-Performanceabnahme. Der kanonische Port bleibt `cfg(test)`; aus diesen Ergebnissen folgt kein behobener UI-Stall und keine erreichte2%-Parität. Verifikation: reguläre Port-Suite101/101 in53,44s und mit Unretained-Command- Buffers101/101 in53,25s; Release-Clippy, Format-/Diff- und Originalquellen-Check bestehen. Die drei NGram-GPU-Tests bestehen auch mit `MLX_METAL_FAST_SYNCH=1` in0,49s. Testlaufzeiten sind keine Modell-Performancewerte. Prüfbeleg: `local-eval-results/20260907-mtplx-port/ngram-resident-check.log`. ### Verbundener Sidecar-Gather und Tabellenauswahl (2026-09-07) `ngram_sidecar::SidecarGather` portiert nun `_SidecarGather` als zusammenhängenden Dateipfad: getrennte read-only Tensor-Mappings mit Random-Advice, sortierte eindeutige I64-IDs und inverse Expansion, optionaler persistenter Prefetch-Pool mit höchstens16 Threads und originaler Chunkformel `clamp(ceil(n/32),1,64)`. Prefetch liest jede Map pro Zeile mit `pread`; erst anschließend sammelt die Generation die Rohzeilen aus den Mappings. Prefetch verändert den Cache nicht. Threads und Aufträge werden vor Freigabe sauber beendet; nur eigene temporäre Testdateien werden entfernt. Der Hot-Cache speichert Rohzeilen-Views auf gemeinsam gehaltene Fetch-Matrizen. Damit behalten verbleibende Zeilen wie NumPy ihren zugrundeliegenden Fetch-Block. Ein HashMap-basierter doppelt verketteter LRU bietet O(1)-Touch/Eviction ohne unbeschränkt wachsende historische Touch-Liste. Misses werden zuerst eingefügt, alle eindeutigen Zeilen danach in sortierter Reihenfolge berührt und erst dann überzählige Einträge entfernt. Die Ergebnisreferenzen überleben diese Eviction. Leere Gathers, deaktivierter Cache und mehr als4096 eindeutige IDs umgehen den LRU vollständig, ohne dessen Zähler/Reihenfolge zu verändern. `gather_np` erzeugt Integer-Arrays/View und die vorhandene originale affine Dequantisierung, ohne einen Graph auszuwerten. Der nicht gestagte `gather` liest hingegen wie `_SidecarGather.__call__` den einmal ausgewerteten ID-Graph auf der CPU. Der Abgleich mit `mlx_to_nd_array` erhält Strides und Byte-Offsets; keine zusätzliche Contiguous-GPU-Kopie oder zweite Auswertung. Die Rohzeilenausgabe bleibt anschließend lazy. `Table::gather` übernimmt die Referenzpriorität: bevorzugte residente Tabelle, sonst Sidecar, sonst Fehler im Sidecar-Modus oder plain Gewicht. `GpuHash::embedding` verwendet jetzt diese gemeinsame Auswahl. 192 tatsächliche dateibasierte Original-Receipts: BF16/F16, raw/Q4x160, Prefetch aus/an, Kapazität0/3/4096 Zeilen, wiederholte/negative IDs, leer, 4096/4097 eindeutige IDs und weitere Decode-Gathers. Exakte Ausgabehashes, LRU-Reihenfolge, Hits/Misses, Eintragszahl und Prefetch-Batches stimmen überein. Original `gather_np` und Original `__call__` liefern dieselben192 Receipts. Rust prüft jede Folge materialisiert-sofort, materialisiert-verzögert und über den nicht gestagten Tabellenpfad mit lazy strided IDs (576 Vergleiche). Ausgaben bleiben auch nach Freigabe von Mappings, Pool und Cache korrekt. Zusätzlicher Routingtest prüft resident/plain Priorität und fehlenden Sidecar. Keine Kernel-/Bridge-Änderung in diesem Abschnitt. Vorhandene Array/View-, Readback- und Dequantisierungsbausteine werden wiederverwendet; Rust-Stdlib und das vorhandene memmap2 genügen, kein neues Crate. Eintrittspunkte nehmen bereits aufgelöste Tensor-Metadaten und Prefetch-/Cache-Einstellungen entgegen. Safetensors-Attach, Umgebungs-/Modellpolicy, Stage-Lifecycle und vollständige Modell-/Produktanbindung bleiben offen. Kein Vollmodell- oder IO-Performance- Vergleich und keine2%-Abnahme; Port weiterhin `cfg(test)`. Verifikation: reguläre Gesamt-Port-Suite103/103 in55,27s; Unretained-Command- Buffer-Suite103/103 in54,87s. Release-Clippy, Format-/Diff- und Quellen-Check bestehen. Fast-Synchronisation besteht mit5/5 NGram-Tests in2,25s. Prüfbeleg: `local-eval-results/20260907-mtplx-port/ngram-sidecar-check.log`. Diese Testlaufzeiten sind keine Modell-Performancewerte. ### Verbundener N-Gram-Stage-Lifecycle (2026-09-07) `ngram_stage::Embedding` verbindet jetzt CPU-Hash, Sidecar, GPU-Graph und History mit dem originalen `stage`/`__call__`-Ablauf. Die CPU-Hashkonstanten werden beim ersten tatsächlichen Stage-Aufruf gelesen und behalten; EOS bleibt der aktuelle Modellwert. Stage selbst schreibt die Cache-History nicht. Gespeichert werden Shape, lazy Embedding, neue rohe History und vorherige History für QA. Kein Sidecar, deaktivierte Stage-Option oder `_stage_disabled` kehren wie die Referenz zurück, ohne eine vorhandene Vorbereitung zu löschen. Tatsächliche Vorbereitungsfehler löschen sie und warnen nur einmal, deaktivieren spätere Versuche jedoch nicht dauerhaft. `forward` verbraucht die Vorbereitung zuerst und prüft nur B/S, nicht Tokenidentität. Passende Vorbereitung aktualisiert erst nach erfolgreicher optionaler QA den Cache und den Consumed-Zähler. Bei stale Shape folgen Bypassed-Zähler und normaler Graph-Fallback. Dieser zählt Graph- Calls und schreibt die neue History **vor** dem Tabellenzugriff, auch wenn der Zugriff danach fehlschlägt. Census-Ausgabe und Warnung folgen der Referenz. Die optionale QA verwendet die originale F32-`allclose`-Kette mit Atol1e-8, Rtol1e-5, NaN-false und expliziter ±Inf-Korrektur. Vorhandene Binary-/Unary- Operatoren sind um LessEqual, LogicalAnd/Or/Not erweitert; die ursprünglichen Kernels stammen unverändert aus der gepinnten Runtime-Metallib. Die boolesche Gesamtreduktion übernimmt die Original-Single-/Two-Pass-Geometrie sowie die strikte64MiB-Grenze und4-Byte-Mindestallokation. Dieser Reducer deckt den dichten Bool-Ausgang der Stage-QA ab, nicht beliebige andere Reduktionspläne. Der gemeinsame `ops::read_i64` folgt der NumPy-Konvertierung für Integer-Arrays: einmal auswerten, dann Strides/Byte-Offsets auf dem gemeinsam gehaltenen Speicher lesen und auf der CPU nach I64 konvertieren. Der Sidecar nutzt denselben Helfer nach seinem originalen Flatten; Stage fügt kein GPU-Flatten oder Cast hinzu. 136 tatsächliche Original-Lifecycle-Receipts mit realer kleiner Sidecar-Datei: raw/Q4, B1/2, 4-Token- und ausgewählte2048-Token-Prefills, jeweils Decode-Folge. Normal, QA, Graph-only, Stage-disabled, stale Shape, andere Tokens gleicher Shape, QA-Mismatch, übersprungene Vorbereitung bei deaktivierter Policy oder fehlendem Sidecar, wiederholter Vorbereitungsfehler, kein Cache, längere History, überschriebene Vorbereitung und Graphfehler sind enthalten. Ausgabe- und History-Hashes, unveränderte History nach Stage, Consumed/Bypassed/Graph-Zähler, Warnstatus, Pending-State und Fehler stimmen unmittelbar und bei verzögerter Ausgabeauswertung überein (272 Vergleiche). Zusätzliche38 Original-Receipts prüfen die QA-Sonderwerte und Reduktionsgrenzen einschließlich >64MiB. Keine neue Metal-/Bridge-Änderung und keine neue Dependency. Policywerte werden explizit übergeben; deren Auflösung, Safetensors-Attach, Loader und gesamte Decoder-/Modell-/Produktanbindung bleiben offen. Der Port ist weiterhin `cfg(test)`. Diese Belege sind keine UI-/Vollmodell-Performanceabnahme. Verifikation: reguläre Port-Suite105/105 in56,27s und Unretained-Command-Buffer- Suite105/105 in56,17s; Release-Clippy, Format-/Diff- und Quellen-Check bestehen. Die sieben NGram-Tests bestehen auch mit Fast-Synchronisation in2,60s. Prüfbeleg: `local-eval-results/20260907-mtplx-port/ngram-stage-check.log`. Testlaufzeiten sind keine Modell-Performancewerte. ### Vollständiger PLE-Aufruf mit Safetensors-Ladeanbindung (2026-09-07) `ple::Ple::forward` verbindet jetzt das tatsächliche NGramEmbedding mit der Projektion, dem Gate und der dilatierten Faltung. Der äußere Stage-Prepass bleibt außerhalb des Aufrufs. Cache-Slot3 wird durch den Lookup vor der Projektion aktualisiert; Slot2 erst durch die Faltung. Die bisherigen numerischen Projektionsoperatoren werden unverändert weiterverwendet. 144 tatsächliche Original-`PLELayer`-Receipts, ohne Ersatz-Embedding: BF16-Tabelle und Q4-Tabelle, dichte und quantisierte Projektionen, Stage/QA/Graph/residenter Pfad, B1/2, 7/2048 Prefill-Tokens und folgende Decode-Schritte einschließlich EOS, kein/leerer/vorbelegter Cache. Die Referenz erzeugt kleine lokale Safetensors und benutzt jetzt auch `attach_sidecar`/`attach_resident`; deren 144 Ergebnisse sind unverändert zu den zuvor direkt angebundenen identischen Tabellen. Rust prüft Ausgabe, Faltungszustand und rohe Token-History sofort und verzögert (288 Vergleiche). `Table::attach_sidecar` übernimmt Metadaten-Defaults, Entfernen eines vorhandenen Plain-Weights, Prefetch-/Hot-Cache-Konfiguration und die existierende mmap-LRU. `attach_resident` materialisiert die ausgewählten Arrays vor Rückkehr, setzt bei Erfolg `prefer_lazy=false` und löscht bei Fehler die residente Bindung. Stage- Flags werden mit den originalen exakten Stringvergleichen gelesen. Der erforderliche CPU-`Load` ist an den vorhandenen Graph/Scheduler/Allocator angeschlossen: eigener Vier-Worker-Load-Pool, unabhängiger Vier-Worker-Pread-Pool, 32MiB-Batches, direkter Rest, CPU-Stream wartet auf das Load-Future. Header und Payload werden über denselben gehaltenen Dateideskriptor gelesen. Worker halten die Zielallokation bis zum Ende ihrer disjunkten Schreibaufträge. Die bestehende Header-Validierung wird weiterverwendet, einschließlich ihrer Schutzgrenzen. Zusätzlicher Loader-Test: leer/klein und unter/auf/über32MiB sowie >64MiB, Payload erst nach Graphkonstruktion geschrieben, Datei vor Auswertung entfernt, sofortige/asynchrone CPU→GPU-Folge, gemeinsame Allocator-Buchung und nachträglich abgeschnittene Datei mit propagiertem Fehler. Keine großen Modellgewichte geladen. Unveränderte Original-Metal-Quellen und Metallib; keine neue Dependency. Offen bleiben die modellweite Residency-/Memory-Plan-Auswahl, Laden/Sanitize der übrigen Gewichte, Decoder-/Gesamtmodell-/Produktanbindung und vollständige Messabnahme. Der Port ist weiterhin `cfg(test)`; diese Nachweise schließen P10 oder das 2%-Gesamtziel nicht ab. Belege: `tests/fixtures/mtplx-ple-connected.jsonl` und `local-eval-results/20260907-mtplx-port/ple-connected-load-check.log`. Verifikation: Port-Suite107/107 in58,72s, abschließende Unretained-Command- Buffer-Suite107/107 in59,00s; Release-Clippy, Format-/Diff- und Quellen-Check bestehen. Der bestehende Safetensors-Boundary-Test besteht ebenfalls. Die abschließenden Fast-Synchronisationschecks bestehen für PLE in2,76s und den CPU-Loader in0,14s. Die Testlaufzeiten sind keine Modell-Performancewerte. ### Verbundene Attention-Matrixpfade und Softmax (2026-09-07) P08/P09: Der gemeinsame BF16-Matmul übernimmt jetzt auch führende Batchachsen, gemeinsames Broadcasting mit zwei ausgesparten Matrixachsen, Stride-Collapse, Broadcast-Batch-in-M-Collapse und ursprüngliche Transpose-/Copy-Vorbereitung. Wide-GEMV, GEMV und NAX-GEMM erhalten die originalen Batchformen/-strides und Dispatchbedingungen; Split-K bleibt auf Batch1 begrenzt. Die vorhandenen dichten Projektionen benutzen denselben Operator. Nicht abgedeckt sind allgemeine Dot-/Vektor-/N1-/Empty-Matmul-Fälle und andere Datentypen oder Geräte. Der Last-Axis-Softmax ist ein eigener lazy Operator mit ursprünglicher Contiguous-Prüfung, Donation oder Stride-erhaltender Allokation, notwendiger Kopie sowie Block-/Looped-Auswahl an der4096-Grenze. BF16/F16 verwenden bei `precise` die originale präzise Spezialisierung; F32 die normale. Der Speicher- Reuse-Test synchronisiert nur seine Eingabevorbereitung: ein GPU-Event-Wait garantiert weder hier noch in der Referenz, dass Completion-Callbacks ihre Data-Referenzen schon freigegeben haben. Keine zusätzliche Synchronisation im Laufzeitoperator oder Evaluator. `attention::sdpa_fallback` verbindet die originalen BF16-Q-Skalierung, GQA-Views, QK-Matmul, Bool-/additive Maskierung, präzisen Softmax und PV-Matmul. Bool-false setzt hier BF16-finfo.min, nicht minus unendlich. Die Routenzuordnung stammt aus MTPLXs gepinntem `fast.cpp` und Metal-SDPA: Qwen hat GQA12/D256; S3–8 überschreitet die Fused-Vector-Bedingung S*GQA<=32. Größere D256-Prefills mit expliziter Array-Maske benutzen ebenfalls diesen Fallback. Das ist eine Quellzuordnung, keine gemessene Ursache für die Gesamt-MTP-Geschwindigkeit. `attention::rows_gather` portiert getrennt den tatsächlichen MTPLX-Aufruf `_qsa_rows_gather_attention`: zwei per-row Gathers über Cache-Achse2, gruppierte Views ohne zwölfmaliges Materialisieren von K/V, BF16-QK **vor** F32-Cast und Skalierung, minus-unendlich-Maskierung, F32-Softmax, BF16-Probabilities und PV. Hier wäre ein Aufruf des obigen SDPA-Fallbacks numerisch und funktional falsch. Der bereits vorhandene Tabellen-Gather wurde zum gemeinsamen Original-`take` mit Gather/Transpose/Squeeze erweitert; NGram benutzt weiterhin dessen Achse0. 14 zusätzliche I32/BF16-Instanziierungen aus unverändertem Gather-Körper und originalem JIT-Wrapper sind exportiert. Keine neue algorithmische Kernelversion, Bridge oder Dependency; die ursprüngliche Runtime-Metallib bleibt unverändert. Tatsächliche Original-Receipts (keine Performance-Mikrobenchmarks): - 34 Batch-Matmul-Fälle, jeweils sofort/lazy:68 exakte Vergleiche. GQA-QK/PV, B1/2, S1/3/8/16/64/2048, Cache-Strides, Transposes, Cross-Broadcast, Batch-Collapse, nicht ausgerichtete Offsets und erforderliche Kopien. - 48 Softmax-Fälle, jeweils mit/ohne gehaltene Eingabe:96 exakte Vergleiche. BF16/F16/F32, `precise` aus/an,17/4097 Spalten, plain/swapped/strided/offset; außerdem Stride- und kontrollierte Donation-Prüfung. - 21 tatsächliche `mx.fast.scaled_dot_product_attention`-Aufrufe, sofort/lazy: 42 exakte Vergleiche. GQA12 oder gleiche Headzahl, bis2048 Prefillzeilen, Cache-Backing-Offsets, keine/Bool/additive Maske, vollständig maskierte Zeile. - 18 tatsächliche MTPLX-Rows-Gather-Aufrufe, sofort/lazy:36 exakte Vergleiche. S1/3/8/16/64,8/17/1025/4097 gewählte Tokens, GQA12 oder gleiche Headzahl, volle/versetzte/strided Cacheansichten; zwei originale Gathers und ein F32-Softmax werden im Dispatch nachgewiesen. **Weiter offen:** Full-SDPA-Auswahl und Bindung, vollständiges Attention-Modul mit Projektionen/RoPE/Cache/Selektor, Decoder/Gesamtmodell und Produktionsumstellung. Diese Operatoren bleiben `cfg(test)`; P08/P09/P16 und das2%-Ziel sind nicht abgeschlossen. Belege: `tests/fixtures/mtplx-{dense-batch,softmax-graph, sdpa-fallback,qsa-rows-attention}.jsonl` und `local-eval-results/20260907-mtplx-port/attention-graphs-check.log`. Verifikation: reguläre Port-Suite111/111 in61,32s, Unretained-Command-Buffer- Suite111/111 in61,78s; die zwei verbundenen Attention-Tests bestehen zusätzlich mit Fast-Synchronisation in0,96s. Release-Clippy, Format-/Diff- und Quellen- Check bestehen. Diese Testlaufzeiten sind keine Modell-Performancewerte. ### Gekachelter portabler Prefill-Gather (2026-09-07) `attention::prefill_gather` verbindet nun auch MTPLXs tatsächlichen `_qsa_prefill_gather_attention`-Ablauf: pro Kachel absolute I32-Positionen, Integer-Divide, vollständige ausgewählte Blöcke, kausaler Tail, Bool-Repeat, Concatenate und sichere Nullindizes für ungültige Slots; danach der oben geprüfte Rows-Gather auf den **vollen** KV-Backings. Keine Vollkontext-Kopie. Das unbenutzte Python-Argument `total_tokens` benötigt keinen Rust-Operand; die Auswahl adressiert wie im Original ausschließlich die übergebenen Backings. Jede Kachel wird vor der nächsten ausgewertet. Bei nur einer Kachel ist das Ergebnis schon ausgewertet; sonst bleibt ausschließlich die abschließende Concatenate-Operation lazy. Die Python-Lokalen werden auch in Rust über die Auswertung hinweg gehalten und erst in Referenzreihenfolge beim nächsten Schleifendurchlauf ersetzt. Zusätzliche Schattenbindungen kurzlebiger Ausdrücke und vorzeitig bewegte Concatenate-Eingaben wurden vermieden, weil sie Donation und Data-Lebensdauer trotz passender Ausgabehashes verändern würden. Die vorhandenen Arange- und Binary-Operatoren übernehmen Startwerte und Integer-Floor-Divide: Letzteres verwendet wie `ops.cpp` den vorhandenen Divide- Kernel ohne True-Divide-Promotion nach F32. Keine neue Metal-/Bridge- oder Dependency-Änderung. Die restliche SDPA-/Attention-/Produktanbindung bleibt offen. 34 tatsächliche MTPLX-Receipts, jeweils mit lazy bzw. vorher ausgewerteten Eingaben (68 Vergleiche): GQA12/gleiche Headzahl, S1/7/17/2048, Kompressionsratio1/4/128, Position0/3/127/511, Kachelgrößen1/4/64/2048, dichte I32- und versetzte/strided I64-Blockauswahl, ungültige negative IDs. Der Referenzgenerator protokolliert die tatsächlichen `mx.eval`-Aufrufe samt Tile-Shapes. Rust prüft deren Reihenfolge/Form im ausgewerteten Ausgabegraph, zwei Gathers und einen F32-Softmax je Kachel sowie das exakte Ausgabehash. Belege: `tests/fixtures/mtplx-qsa-prefill-gather.jsonl` und `local-eval-results/20260907-mtplx-port/prefill-gather-check.log`. Das ist weiterhin ein `cfg(test)`-Portnachweis, keine P08-/P16-Gesamtabnahme. Verifikation: reguläre Port-Suite112/112 in62,24s, Unretained-Command-Buffer- Suite112/112 in62,50s; alle drei Attention-Tests mit Fast-Synchronisation in1,37s. Release-Clippy, Format-/Diff- und Quellen-Check bestehen; ursprüngliche Metallib unverändert. Die Testlaufzeiten sind keine Modell-Performancewerte. ### Fused-Vector-SDPA und typisierte Metal-Konstanten (2026-09-07) Der BF16/D256-Vector-SDPA ist jetzt als eigene Primitive verbunden. Die gemeinsame `attention::scaled_dot_product`-Auswahl verwendet bei Qwens normalen Aufrufen ohne bzw. mit expliziter Array-Maske den originalen Vector-Pfad für S<=8, S<=T und S*GQA<=32; sonst den bereits geprüften D256-Fallback. Der direkte Vector-Aufruf unterstützt zusätzlich die kausale Maske; bei S1 bleibt ihr Kernel-Flag wie im Original ausgeschaltet. Die Bindung übernimmt Q-/KV-/Masken-Kopierbedingungen, Query-Donation, Allokationsreihenfolge, Offset-/Stride-Bindings, Bool-/additive Maske und Ein-/Zwei-Pass-Auswahl. Zwischenpuffer werden wie in der Referenz als Encoder-Temporaries gehalten. Die drei unveränderten Originalkerne kommen direkt aus derselben gepinnten Runtime-Metallib. **Live korrigierte Hardwarezuordnung:** `mx.device_info` meldet für diesen Apple M5 Max `applegpu_g17s` (Max), nicht `...d` (Ultra). Beim ersten Zwei-Pass- Vergleich führte die falsche Zuordnung zu einem abweichenden Ausgabehash. Für GQA12 ergibt die tatsächliche Max-Policy64 Blöcke bei T1024,128 bis8192, 256 bis32768,512 bis65536, danach1024; nicht die Ultra-Grenzen. Die Auswahl verwendet jetzt den bereits vorhandenen Architektur-Bridge-Helfer gemeinsam mit dem Scheduler und dem `MLX_METAL_GPU_ARCH`-Override. Alle originalen Architekturzweige und `MLX_SDPA_BLOCKS` mit `atoi`-Semantik/32er-Aufrundung sind abgebildet. Die zuvor falsche Annahme ist kein Modell-Performancebefund. Der gemeinsame Bridge-Konstantentyp unterstützt jetzt Bool und echtes I32 statt ausschließlich Bool. Der Pipeline-Cache-Schlüssel enthält auch den Typ; ungültige Typen, Bool-Werte und doppelte Indizes werden weiterhin verworfen. Alle alten Bool-Aufrufe sind auf denselben neuen ABI-Typ umgestellt. Keine neue parallele Dispatch-Bridge und keine Änderung der Kernelkörper. 48 tatsächliche Referenzfälle, jeweils lazy/vorbereitet (96 exakte Vergleiche): B1/2, GQA12, S1/2, T17/33/1023/1024/16384/65536, transponierte Query bzw. Copy-erforderliche Strides, versetzte KV-Backings, keine/Bool/additive/kausale Maske. Der Dispatch prüft die tatsächlich erwartete Ein-/Zwei-Pass-Folge; wechselnde Blockzahlen prüfen auch die Integer-Konstante und Cachetrennung. Belege: `tests/fixtures/mtplx-sdpa-vector.jsonl` und `local-eval-results/20260907-mtplx-port/vector-sdpa-check.log`. Offen bleiben Full-SDPA einschließlich NAX-D256-Causal-Split, Sinks/andere Datentypen und Head-Dimensionen außerhalb des installierten Qwen-Aufrufs, vollständiges Attention-/Modulrouting, Modell-/Produktanbindung und P16. Der kanonische Port bleibt `cfg(test)`; keine Vollmodell-Performanceabnahme. Verifikation: reguläre Port-Suite113/113 in64,07s, Unretained-Command-Buffer- Suite113/113 in63,75s; Fused-SDPA-Fast-Synchronisationscheck in1,25s. Release-Clippy, Format-/Diff- und Quellen-Check bestehen; ursprüngliche Metallib unverändert. Die Testlaufzeiten sind keine Modell-Performancewerte. ### Originale RoPE-Graphen und KV-Cache-Objektsemantik (2026-09-07) `rope.rs` bildet `_rope_inv_freq_and_scaling`, `_rope_cos_sin`, `_build_mrope_axes`, `_mrope_cos_sin` und `_apply_partial_rope` als gewöhnliche Graphknoten ab. F32-Arange, Power, Sin/Cos und Typgrenzen verwenden dieselben Runtime-Kerne, keine CPU-Frequenztabelle und keinen Ersatz-RoPE-Kernel. Host-F64 bleibt auf die originalen Python-math-Schritte von statischem YaRN beschränkt. Der Modell-Konfigurationsparser wird dadurch noch nicht ersetzt. 48 tatsächliche MTPLX-Referenzfälle, jeweils lazy/vorbereitet:96 exakte Vergleiche für Frequenzen, Cosinus, Sinus und rotierte BF16-Ausgabe. Enthalten sind Rotary64 und256, partielle/vollständige Rotation, S1/7/64/2048, Positionen bis1048576, Default/static YaRN einschließlich Amplituden-/mscale-Verhältnis und ungekürzter Rampe sowie gleiche, interleaved und abschnittsweise M-RoPE-Achsen. Geslicte Eingaben bleiben geslict. Die Referenz-Funktionen, nicht eine nachgebaute Python-Formel, erzeugen `tests/fixtures/mtplx-rope-graph.jsonl`. `cache.rs` portiert den von QSACache benutzten gewöhnlichen KVCache: 256er-Wachstum, Teilkapazitäts-Slice vor Wachstum, Full/Concatenate/SliceUpdate, Trim und State-Roundtrip. `ops::slice` und `slice_update` teilen die ursprüngliche Indexnormalisierung; Full und SliceUpdate verwenden die gemeinsamen Copy-Kerne mit den originalen Scalar/Vector/General-/Donation-Regeln. GeneralGeneral-Copy verwendet bei Ausschnitten weiterhin die Datengröße des vollständigen Ziel-Arrays für Large-Dispatch und Encoder-Abhängigkeiten. **Tatsächlich gefundene Besitzabweichung:** Eine reine `Array::clone`-Übernahme bildete Python-Aliase auf `cache.keys`/`values` nicht ab. `mlx_set_item` überschreibt den Descriptor des bestehenden Python-Arrayobjekts; gehaltene Python-Objektaliase folgen dieser Änderung, bereits gebaute Graphknoten behalten dagegen ihren ursprünglichen Descriptor. Der Rust-Cache trennt deshalb `Rc>` auf der Modellobjekt-Ebene von den unveränderten Array-Deskriptoren im Graphen. Wachstum ersetzt das Objekt, SliceUpdate ersetzt nur seinen Descriptor. Das ist weder eine zusätzliche GPU-Kopie noch ein geänderter Shader. Die12 unveränderten tatsächlichen KVCache-Referenzfälle bestehen danach exakt: Startlängen0/1/255/256/257/2048, mehrere Updates, Trim/Overwrite, Wiederherstellung eines gehaltenen Zustands, vollständiger Trim und Wiederaufnahme; jeweils sofortige bzw. verzögerte Auswertung. Geprüft werden sowohl logische Zustände als auch vollständige Backings und Kapazitäten. Beim vollflächigen Ersatz kann ein transponiertes Eingabelayout erhalten bleiben; der reine Test-Readback wurde deshalb wie NumPy in logischer C-Reihenfolge exportiert. Die Referenzhashes wurden nicht angepasst. Zusätzliche SliceUpdate-Prüfungen decken negative Strides, leere Updates, Broadcast/Typkonversion und tatsächliche Donation ab. Nur12 weitere originale F32/I32-Gather-Instanziierungen für M-RoPE;15 Custom- Kernelkörper,35 Custom-Einstiege und22 Runtime-Quellblöcke sind weiterhin unverändert zur Referenz. Der Export enthält jetzt170 Runtime-Einstiege; die originale Runtime-Metallib bleibt bytegleich. P08 bleibt offen: vollständiger Attention-Aufruf mit QKV-/Indexer-Fusion, QSA-Arraygraph und dessen veränderlichen Cacheobjekten, sämtliche Auswahlzweige und das nachfolgende Modellrouting sind noch nicht verbunden. Insbesondere darf der bisherige Buffer-/Rc-Pfad die hier aufgedeckte Objekt-/Descriptor-Unterscheidung bei der Integration nicht verlieren. Modell-/Produktanbindung und P16 sind weiterhin offen; der Port bleibt `cfg(test)`. Keine Modell-Performance- oder Responsiveness-Abnahme aus diesen Fixtures. Belege: `tests/fixtures/mtplx-kv-cache-graph.jsonl` und `local-eval-results/20260907-mtplx-port/rope-cache-check.log`. Verifikation: Port-Suite115/115 in64,78s, Unretained-Suite115/115 in64,77s; zusätzliche Fast-Synchronisationschecks: RoPE1/1 in0,49s und KVCache1/1 in0,29s. Release-Clippy, Format-/Diff- und Quellenprüfung bestehen. Die Laufzeiten bezeichnen Modell-freie Prüfungen, keine Inferenz-Performance. ### Direkte Sparse-Attention-Consumer im Arraygraph (2026-09-07) `sparse_attention.rs` bindet jetzt die unveränderten MTPLX-Körper `qsa_flash_skip.py::_SRC` und `qsa_prefill_flash.py::_SOURCE` als jeweils eine CustomKernel-Primitive ein. Decode übernimmt die originalen Flatten-Aufrufe, Host-Parameter, GQA-Spezialisierung und256 Threads; Prefill verwendet32 Threads pro (Query-Zeile, KV-Head) und die originalen Metal-4-MPP-Matmulfragmente. Es gibt weder ein Gather-/Dense-Ersatzverfahren innerhalb dieser Primitive noch einen stillen Retry nach einem Dispatchfehler. Der Prefill-Aufruf übernimmt die statischen Unterstützungsbedingungen: macOS>=26.2 und GPU-Generation17 (Telefonklasse18), aktiver GPU-Stream, B1/H24/KV2/D256, BF16/F16, I32-/Bool-Selektionen[S,512], S>1, exakter Suffix, Kapazitätsgrenze, maximal1048576 Tokens, mehr als512 vollständige Blöcke und Host-Scale exakt0.0625. Die Plattformantwort ist wie `_mlx_nax_available` gecached; die Bridge liefert nur Betriebssystem-/Gerätedaten, Rust entscheidet. Die Scale-Prüfung erfolgt auf Host-F64, vor der originalen F32-Kernelkonversion. Ausgabeallokation, Input-Bindings und Lebensdauer folgen CustomKernel: Decode verwendet den vorhandenen `gdn::custom_evaluate` einschließlich General-Copies nicht zeilenkontiguierlicher Argumente und Encoder-Temporaries. Prefill übernimmt `ensure_row_contiguous=False` und bindet alle fünf Input-Stridetabellen sowie Byte-Offsets direkt. Die kanonischen Tests prüfen bei vorab ausgewerteten Eingaben ausdrücklich genau einen Prefill-Dispatch, auch bei geslicten Features und Selektionstabellen; keine versteckte KV-Kopie. 50 tatsächliche MTPLX-Fälle, jeweils lazy/vorbereitet:100 exakte Vergleiche. Decode: GQA12/1, nur Tail bzw.512/17 ausgewählte Blöcke, T3/4099/2052. Prefill: S2/8/137/2048, Start2050/8191/32767/2048; BF16/F16, transponierte Query, ungerader Elementoffset, nichtkontiguierliche Features, Selektion mit Strides, ungültige IDs und Gültigkeitslücken bis Slot511. Die Referenz ruft die beiden tatsächlichen Sparse-Kerne direkt auf, keine nachgebaute Formel. Belege: `tests/fixtures/mtplx-sparse-attention.jsonl` und `local-eval-results/20260907-mtplx-port/sparse-attention-check.log`. Der Quellenexport umfasst nun17 unveränderte Kernelkörper und41 Custom- Einstiege;22 Runtime-Quellblöcke/170 Runtime-Einstiege und die originale Runtime-Metallib bleiben unverändert. Die zusätzlichen instanziierten Decode-Varianten sind BF16/F16 mit GQA1/12; andere GQA-/Dtype-Spezialisierungen sind damit nicht als abgedeckt behauptet. P08 ist weiterhin offen: Der vollständige Attention-Aufruf muss QKV-/Indexer- Fusion, Norm/RoPE, KV-Update, Vision-Bypass und alle originalen Auswahlzweige zusammenführen. Besonders die requestbezogene Prefill-Phase und die 32K-Crossover-Policy dürfen nicht durch bloßes `prefill_supported` ersetzt werden. Der kanonische QSA-Indexer-/Cachegraph, Modell- und Produktanbindung sowie P16 fehlen weiterhin. Keine Vollmodell-Performance-Abnahme aus diesen Tests und kein produktiver Verhaltenswechsel. Verifikation: gemeinsamer Release-Lauf116/116 in64,16s vor der abschließenden Plattform-Cache-/Host-F64-Präzisierung. Auf dem finalen Code besteht der gesamte Unretained-Lauf116/116 in65,21s; der fokussierte Normal- und FastSync-Lauf jeweils1/1 in1,75s. Release-Test-Clippy, Format-/Diff- und Quellenprüfung bestehen. Diese Zeiten sind Prüfzeiten ohne Modell, keine Performance-Abnahme. ### Vollständige QSA-Blockmaskenrekonstruktion (2026-09-07) `attention::blocks_to_dense_mask` übernimmt den tatsächlichen `_qsa_blocks_to_dense_mask`-Graph: zeilenweise vollständige Blöcke, originale I32-Vergleiche/Bool-Bitoperationen, ungültige IDs auf eine zusätzliche Sentinel-Spalte, `put_along_axis`, Sentinel-Slice, Repeat, optionale Null-Padding- Spalten, Tail und abschließende Kausalmaske. Dies ist der originale Consumer- Fallback, kein Ersatz für den zuvor portierten direkten Flash-Prefill-Zweig. Die gemeinsame ScatterAxis-Primitive übernimmt Cast/Squeeze/Broadcast-Reihenfolge, Scalar-/Vector-/General-Quellkopie, Vector-Donation, leere Updates, Achsen- und Stride-Bindings sowie die originale Dispatch-Geometrie. Bool/I64-QSA verwendet jetzt alle vier Update-/Index-Layoutkombinationen und Int-/Int64-Adressierung des unveränderten Runtime-Kernels:22 unveränderte Runtime-Quellblöcke und176 Runtime-Einstiege;17 Custom-Körper und41 Custom-Einstiege bleiben unverändert. Keine selbstgeschriebene Scatter-/Masken-Metal-Implementierung. 44 direkte MTPLX-Maskenfälle und64 direkte `put_along_axis`-Fälle werden lazy und vorab ausgewertet verglichen:216 exakte F32-Readback-Hashes. Masken decken S0/1/2/5/8/9/137/2048, Kontext bis32904, Ratio1/4/7, leere Selektionen, gültige/ungültige/duplizierte IDs, vollständig gesperrte Blöcke und geslicte Selektionstabellen ab. Scatter prüft Rank1/2/3, Achsen0/1, skalare/vollständige Updates, negative Indizes und skalare/Offset-/Strided-Quellen. Zusätzlich: führende Singleton-Updates, Achsenfehler, leere Updates und nachgewiesene Vector-Donation ohne zusätzlichen Kopierdispatch. Belege: `tests/fixtures/mtplx-qsa-dense-mask.jsonl`, `tests/fixtures/mtplx-scatter-axis.jsonl` und `local-eval-results/20260907-mtplx-port/qsa-mask-scatter-check.log`. Gemeinsame Release-Verifikation:118/118 normal in68,82s und118/118 mit unretained Command Buffers in68,04s. Release-Test-Clippy, Format-/Diff- und Quellenprüfung bestehen. Das sind modellfreie Prüfzeiten, keine Inferenzdaten. P08 bleibt bis zum vollständigen QSA-Indexer-/QSACache-/Attention-Aufruf und der Produktintegration offen. Keine Modellmessung, kein Abweichen vom vollständigen Port wegen Laufzeiten. ### Positionaler QSACache im kanonischen Arraygraph (2026-09-07) `cache::QsaCache` verwendet den bereits portierten KVCache und dessen `ArrayObject`-Semantik. Raw-/Pooled-Schreibbereiche liegen an absoluten Positionen; Vergrößerung erfolgt geometrisch mit256er-Ausrichtung, nicht durch Anhängen oder Vollkopien je Dekodeschritt. Originale Full/SliceUpdate/ AsType-/Transpose-/View-Primitiven bilden die Mutationen ab; keine neue Puffer-COW-Implementierung neben dem Arraygraph. Der FP32-Spiegel wird beim ersten Zugriff aus dem vollständigen vorhandenen Pooled-Inhalt aufgebaut, bei Schreibzugriffen inkrementell aktualisiert und nach Session-Restore verworfen. Eine Reservierung vergrößert in MTPLX den Spiegel ausdrücklich nicht sofort; diese Reihenfolge bleibt erhalten. Die originale `nbytes`-Eigenschaft zählt KV/Raw/Pooled, aber nicht den abgeleiteten Spiegel. Dies wird unverändert übernommen, nicht als Messung des gesamten realen GPU-Speicherverbrauchs ausgegeben. `QSAIndexer::_ensure_compiled_backings` ist mit dem Cache verbunden: Originale Zweierpotenz-Buckets, ausstehende Reservierungen und der physisch notwendige ceil(S/ratio)-Pooling-Bereich werden vor der Graphausführung berücksichtigt. Session-Restore behält die vier Arrayobjekte, setzt Reservierungen auf die restaurierten Ausdehnungen zurück und rekonstruiert den Spiegel erst bei Bedarf. 16 direkt ausgeführte MTPLX-Lifecycle-Sequenzen prüfen1896 exakte Tensor-Hashes sowie Offsets, Kapazitäten, Reservierungen und `nbytes` nach jedem Schritt: BF16/F16/F32, Ratio1/4/7, Indexbreite17/32/128, Initiallängen0/1/255/256/257/1025, sofortige/verzögerte Auswertung, gehaltene Arrayobjekte und geslicte Zustände, Rollback, Überschreiben, Restore, Mirror-Views und1025-Token-Replay-Reservierung. Belege: `tests/fixtures/mtplx-qsa-cache-graph.jsonl` und `local-eval-results/20260907-mtplx-port/qsa-cache-graph-check.log`. Die erste gebündelte Referenzausgabe war abgeschnitten und enthielt dadurch eine syntaktisch gültige, aber vermischte Zeile. Alle aus abgeschnittenen Ausgaben übernommenen Zeilen wurden verworfen und einzeln aus unveränderten Originalaufrufen neu erfasst. Keine Anpassung von Implementierung oder Referenzhashes an einen fehlgeschlagenen Vergleich. Verifikation:119/119 gemeinsame Release-Tests normal in67,06s und119/119 unretained in67,38s; fokussierter FastSync-Lauf1/1 in1,00s. Release-Test-Clippy, Format-/Diff- und unveränderte Quellenprüfung bestehen. Das sind modellfreie Prüfzeiten, keine Inferenz-Performance-Werte. P08 bleibt offen: Die vollständige kanonische Indexer-Ausführung inklusive kompiliertem Graphbank-Pfad und das Attention-Modul müssen diese Cache-Objekte noch nutzen. Der Port bleibt `cfg(test)`; keine Produkt-/Performance-Parität. ### Parametrisierte QSA-Query-/Pooling-Primitiven (2026-09-07) `qsa_prepare.rs` übernimmt die öffentlichen Query-/Pooling-Aufrufe aus `qsa_indexer_prepare.py` einschließlich statischer Eignungsprüfung, BF16/F16/F32, Kopfbreiten bis128, geradem partiellem/vollem RoPE, beliebigem positivem Pooling-Verhältnis, RMS-Epsilon und positiver endlicher Attention-Skalierung. Host-I32-Positionen werden zu einer Array-Konstante; Tensor-Positionen werden nur auf ein I32-Element validiert und umgeformt, ohne `.item()` oder Synchronisation. Die Spezialisierung verwendet die bereits hashgeprüften Originalkörper `_prepare_queries_kernel` und `_pool_keys_kernel` aus dem vorhandenen Export. Nur Header-Konstanten, Datentyp-Instanziierung und Exportname ändern sich; die Arithmetik bleibt bytegleich. Der vorhandene native CustomKernel-Compiler verwendet Safe-Math und die originale Sprachversion. Der Pipeline-Schlüssel enthält auch EPS-/Skalierungsbits, damit unterschiedliche Konfigurationen nicht versehentlich dieselbe Kompilierung verwenden. Originale Ausgabeallokation vor Kompilierung, vier Array-Inputs, drei Stride-Tabellen, Byte-Offsets und Datenlebensdauer bleiben erhalten. `ensure_row_contiguous=False`: keine impliziten General-Copies. Query verwendet 32 Threads je Zeile/Kopf, Pooling32 je Block; kein Fehler-Retry auf Eager. 72 direkte MTPLX-Fälle mit je zwei Ausgaben werden lazy/vorbereitet geprüft: 288 exakte Tensorvergleiche. S1/3/7/137/2048, H1/2/3/4/7, D2/17/64/128, RoPE2/16/32/64/128, Ratio1/3/4/7/8, negative und große Positionen, Plain-/Offset-/Strided-/Broadcast-Inputs, dynamische GPU-Positionen sowie unterschiedliche EPS bei sonst gleichen Parametern. Vorbereitete Inputs erzeugen genau zwei Dispatches; die dynamischen Kernelkörper werden zusätzlich byteweise mit den geprüften Exportkörpern verglichen. Belege: `tests/fixtures/mtplx-qsa-prepare-graph.jsonl` und `local-eval-results/20260907-mtplx-port/qsa-prepare-graph-check.log`. Verifikation:120/120 gemeinsame Release-Tests normal in67,95s und120/120 unretained in68,37s; fokussierter FastSync-Lauf1/1 in0,82s. Release-Test-Clippy, Format-/Diff- und Quellenprüfung bestehen. Das sind modellfreie Prüfzeiten, keine Inferenz-Performance-Werte. P08 bleibt offen: Diese Primitiven müssen mit dem vollständigen kanonischen QSAIndexer einschließlich Eager-Orakel und kompiliertem Graphbank-Pfad sowie mit Attention/Modell/Produktausführung verbunden werden. Weiterhin `cfg(test)`; keine Vollmodellmessung oder Rücknahme aufgrund isolierter Laufzeiten. ### Gemeinsame Float-Summen und QSA-Mittelwert (2026-09-07) `reduce.rs` übernimmt für BF16/F16/F32 die gemeinsame Sum-Factory und den Reduktionsplan aus `ops.cpp`, `backend/common/reduce.cpp` und `backend/metal/reduce.cpp` der gepinnten MTPLX-Laufzeit. Keine neuen Metal- Körper: sämtliche Reduktionskernel stammen aus der unveränderten originalen Metallib. Die drei bisherigen speziellen GDN-/PLE-/HC-Summen wurden entfernt; ihre kanonischen Modellgraphen verwenden jetzt dieselbe Sum-Operation. Enthalten sind sortierte/validierte Achsen, `keepdims`/Squeeze, No-op-Achsen, leere Reduktionen mit dem originalen Init-Kernel, zusammengefasste reduzierte Achsen, Stride-Sortierung, General-Copy nur beim originalen GeneralReduce-Plan, Row-Small/Simple/Looped sowie Col-Small/Looped/LongColumn/TwoPass und AllReduce mit originalen Schwellen, Zwischenpuffern, Argumentlayouts und Threadgeometrien. Shape-Collapse und zweidimensionale Grid-Faktorisierung werden mit den bereits portierten Views geteilt. Der Runtime-Identitätszweig bewahrt beim Vector-Copy auch kompakte Broadcast-Speicherung; er darf daraus keinen Full-Fill machen. `mean_f32` bildet genau den im QSA-Eager-Pooling benötigten Ausdruck ab: expliziter F32-Input, Sum und anschließendes Multiply mit einem aus Host-F64 auf F32 gerundeten Kehrwert. Kein Divide, eigener Mittelwertkernel oder Zusammenziehen mehrerer Primitiven. Dies ist kein vollständiger allgemeiner Mean-/Integer-Reduce-/Shapeless-Compiler-Port. 232 tatsächliche MTPLX-Referenzfälle werden lazy und mit vorbereiteten Eingaben geprüft:928 bitgleiche Tensorvergleiche für Sum und F32-Mean. Enthalten sind alle neun Kernelfamilien, ein-/mehrdimensionale Reduktionen, zwei und fünf Kernel-Reduktionsdimensionen, Plain-/Offset-/Transpose-/Strided-/Reverse-/ Broadcast-Layouts, No-ops und leere Achsen. Grenzfälle decken insbesondere 31/32 Outputzeilen, Breiten512/513/1024/1025, Spaltenlängen31/32/256/257/ 1023/1024/32768 sowie AllReduce4096/4097 und die64-MiB-Schwelle ab. Zusätzlich werden konkrete Kernelnamen, Dispatch-/Threadgroup-Geometrien und Threads-vs-Threadgroups an14 ausgewählten Grenzen geprüft. Ein separater Runtime-Identitätscheck prüft physische Broadcast-Datengröße und Strides. Belege: `tests/fixtures/mtplx-sum-graph.jsonl` (SHA256 `d0963276ff75305d7903b91cb34f8d0db2472330fba444199f70dfd7fbebcdd1`) und `local-eval-results/20260907-mtplx-port/sum-graph-check.log`. Gemeinsame Release-Suite:121/121 normal in69,63s und121/121 unretained in71,85s. Nach der abschließenden Korrektur des Runtime-Identitätszweigs bestehen auch die fokussierten Checks normal in2,39s, unretained in2,27s und FastSync in2,32s, jeweils1/1 einschließlich aller928 Tensorvergleiche und Dispatch-Verträge. Die vollständigen Suites liefen vor dieser letzten Identitätskorrektur. Release-Test-Clippy, Format-/Diff- und unveränderte Quellenprüfung bestehen. Prüfzeiten sind keine Modell-Performance-Werte. P08 bleibt offen: insbesondere Sort/Argpartition für den Eager-Indexer, dessen vollständige Auswahl-/Cache-/Graphbank-Kette, Attention und produktive Modellintegration. Der Port bleibt `cfg(test)`. Keine Aussage zur UI-Responsivität oder erreichten Performance-Parität; keine Rücknahme aufgrund isolierter Laufzeiten. ### Kanonischer Float-Matmul und verbundener QSA-Score-Pfad (2026-09-07) `dense.rs` verwendet jetzt eine gemeinsame Matmul-Factory für BF16/F16/F32, Typ-Promotion, Vektoren, Matrix-/Vektorprodukte, Broadcast-Batches, statisches Flatten/Unflatten und leere Matrizen. `nn.Linear` delegiert direkt an diese Factory; seine duplizierten Expand-/Reshape-/Squeeze-Pfade wurden entfernt. Alle bisherigen Attention- und HC-Aufrufer verwenden dieselbe Operation. Der Metal-Backendport für den M5 Max übernimmt aus dem gepinnten `backend/metal/matmul.cpp` beide GEMV-Richtungen, DotProduct mit F32-Partials, originalem AllReduce und Scalar-Copy, F16/BF16-GEMV-Wide (ausdrücklich nicht für F32), NAX/SIMD-Split-K und reguläre NAX-/SIMD-GEMM-Auswahl. Kernel, Partitions- größen, Schwellen, Strides, Byte-Offsets, Zwischenpuffer, Function Constants und Dispatch-Geometrien stammen aus dieser Referenz. Keine neuen Metal-Körper. `MLX_ENABLE_TF32` wird wie `env::enable_tf32` einmal mit `atoi` gelesen, Default1; TF32-off wählt die originalen SIMD-F32-Kernel, Vektoren bleiben bei GEMV. Dies erweitert den M5-Max-Port, nicht Complex-Matmul oder den Shapeless-Compiler. `attention::qsa_scores` verbindet den ursprünglichen Ausdruck aus `qsa_indexer_prefill_scores`/`QSAIndexer._select_eager`: F32-Query-Cast bei bereits F32-Poolingoperand gemäß Originalvertrag, Matmul, ReLU je Kopf, Sum über Achse2, Division durch Host-F64-sqrt(D), auf F32 gerundet, und Auswahl von Batch0. Der zuvor portierte gemeinsame Reduktionspfad wird direkt verwendet. 228 zusätzliche Original-Matmul-Fälle sind mit TF32 on/off erfasst: BF16/F16/F32, gemischte Eingabetypen, alle vier Transponierungsrichtungen, Dot-/linke/rechte Vektoren, Kreuz-Broadcasts, Copy-/Offset-/Collapse-/Flatten- Layouts, ungerade K, Split-K-Grenzen und leere Matrizen. Lazy/vorbereitete Ausführung ergibt456 bitgenaue Tensorvergleiche über beide TF32-Prozesse. Zusätzlich bestehen384 vorhandene direkte MTPLX-QSA-Score-Receipts jetzt auch durch den kanonischen Arraygraph, einschließlich S2048, N1/7/16/32/40/63/64/ 128/129/513 und acht Speicherlayouts. Zusammen840 neue Matrix-/Score- Vergleiche; die bisherigen68 BF16-Attention-Vergleiche bleiben erhalten. Konkrete F32-Kernelnamen und Threadgeometrien für GEMV, beide Split-K-Varianten und gebatchte reguläre GEMM werden zusätzlich geprüft. Beim Erfassen der Referenz stürzte `numpy.asarray` auf einem leeren F32- Matmul-Ergebnis ab. Ein unabhängiger Minimalaufruf bestätigt: `mx.eval` schließt ab; erst das Auslesen der Null-Datenadresse stürzt ab. Der gemeinsame Fixture-Emitter hasht daher bei `size==0` die leere Bytefolge nach erfolgreichem Eval, ohne NumPy-Lesen. Keine Änderung an Referenzmodell/-runtime, Berechnung oder nichtleeren Hashes. Die abgebrochene F32-Capture-Gruppe wurde vollständig neu erfasst. Form und Abschluss leerer Ergebnisse bleiben geprüft. Belege: `tests/fixtures/mtplx-dense-float.jsonl` (SHA256 `24ac569b5fe6f4dc6757cb21870bc3d9ae0fd2c7eff690240284b61d0ce76037`), vorhandene `qsa_f32_score_*`-Receipts und `local-eval-results/20260907-mtplx-port/dense-float-graph-check.log`. Verifikation des finalen Standes:123/123 gemeinsame Release-Tests mit Default-TF32 in72,44s;123/123 mit `MLX_ENABLE_TF32=0` und unretained Command Buffers in72,34s; fokussierte Matrix-/QSA-Gruppe3/3 mit TF32 und FastSync in2,00s. Release-Test-Clippy, Format-/Diff- und unveränderte Quellenprüfung bestehen. Diese Prüfzeiten sind keine Inferenz-Geschwindigkeitswerte. P08 blieb an diesem Messstand offen: kanonisches Sort/Argpartition, fehlende Indexier-Dtypes, vollständige Indexer-Auswahl/Cache-/Compiled-Graphbank und Attention-Aufruf. Auch Modell-/Produktausführung und abschließende Performance-Abnahme bleiben offen. Der Port ist weiterhin `cfg(test)`; kein Vollmodell-Speed oder UI- Responsiveness-Nachweis wird aus diesen modellfreien Prüfungen abgeleitet. ### Gemeinsames kanonisches Sort/Argpartition (2026-09-07) `sort.rs` portiert die vier ursprünglichen Factories Sort, ArgSort, Partition und ArgPartition und deren gemeinsamen Metal-Merge-Sort. Partition bleibt wie in der Referenz ein vollständiger Sort; `kth` wird normalisiert, geprüft und im Graph-Primitiv erhalten. Negative Achsen, Flatten bei fehlender Achse, BF16/F16/F32/I32/U32/I64/U64, Layout-/Offset-Auswertung, der originale Contiguous-/Noncontiguous-Dispatch, Blockgrößengrenzen einschließlich der 64-Bit-Ausnahme, Ping-Pong-Partition/Merge und abschließende Vector-/General- Kopie verwenden den ursprünglichen Ablauf und unveränderte Metallib-Kernel. Die Kopie benutzt die vorhandenen gemeinsamen Copy-Funktionen. Der bisherige Buffer-Argsort für Router, MoE und QSA ist auf einen Adapter mit denselben Form-/Pufferprüfungen reduziert; seine duplizierte Sortier- und Kopierschleife wurde entfernt. Adapter und kanonischer Arraygraph gehen durch dieselbe Backendfunktion. Zurückgegebene Zwischenpuffer bleiben für vorhandene Buffer-Aufrufer bis zum GPU-Abschluss erhalten; im Arraygraph werden sie vom Encoder gehalten. 161 zusätzliche Original-Referenzfälle (23 Profile × sieben Dtypes) prüfen jeweils alle vier Operationen, verzögert und mit vorbereiteten Eingaben: 1.288 bitgenaue Tensorvergleiche. Enthalten sind gleiche Sortierschlüssel, negative Werte, beliebige Achsen, Transponierung, Schritt-/negative Strides, Broadcast, Offset, Flatten sowie Ein-/Mehrblockgrenzen bis8.193 Elemente. Für die Grenzprofile werden zusätzlich konkrete Kernel-Namen, Blockgrößen, Grids und Anzahl der Merge-/Partition-Runden geprüft. Ungültiges `kth` wird vor dem Dispatch abgewiesen. Leere Sortierachsen sind kein abgenommener Fall: Der Originalbackend teilt durch die Achsengröße; der Rust-Port liefert bei0 einen Fehler statt einen erfolgreichen Sort vorzutäuschen. Beleg: `tests/fixtures/mtplx-sort-graph.jsonl`, SHA256 `a655665801dae88d9186faa60c4678bbf5af08b8b4797e95d836d5ab51cbd2b8`. Erfassung direkt mit `sort_graph_fixtures` im gepinnten MTPLX-0.32.2-Prozess, ohne Modellgewichte oder Downloads. Der erste gemeinsame Release-Durchlauf besteht124/124 Tests in73,96s, einschließlich bestehender Router-, MoE- und QSA-Aufrufer. Dieser Lauf enthält die Ergebnisprüfungen; die anschließend ergänzten Dispatch-Verträge werden im abschließenden Lauf geprüft. Der finale gemeinsame Durchlauf mit unretained Command Buffers besteht 124/124 Tests in73,13s, einschließlich der Dispatch-Verträge. Die fokussierte FastSync-Prüfung besteht ebenfalls. Release-Test-Clippy, Format-/Diff-Prüfung und unveränderte Quellenprüfung bestehen. Vollständiges Prüfprotokoll: `local-eval-results/20260907-mtplx-port/sort-graph-check.log`. Diese Prüfzeiten sind keine Modell-Performancewerte. P08 bleibt offen: fehlende Indexier-Dtypes, vollständige kanonische Indexer-Auswahl/Cache-/Compiled-Graphbank und Attention-Aufruf. Der gesamte kanonische Port ist weiterhin `cfg(test)`; Produktmigration, vollständige Funktionsparität, UI-Responsivität und die2%-Performance-Abnahme sind damit ausdrücklich nicht abgeschlossen. ### Verbundene kanonische Eager-QSA-Auswahl (2026-09-07) `attention::select_eager` verbindet nun den zuvor portierten F32-Scoregraph und Sort/Argpartition mit dem tatsächlichen `QSAIndexer._select_eager`- Ablauf, dem kanonischen QSACache und allen fünf Ausgabeformen. Der gepoolte F32-Spiegel kommt direkt aus `QsaCache::pooled_f32_view`, einschließlich seiner gepaddeten, nicht-kontiguierlichen Ansicht. Causal-Blockgrenzen, Minus-Unendlich-Maskierung und F32-Tie-Break werden vor Argpartition wie im Original berechnet; die gewählten Indices bleiben eine Array-Ansicht. Die Rückgabereihenfolge ist unverändert: chronologische Prefill-Blöcke mit Gather-Validität und Nullersatz; Flash-Decode mit Host-Tailgrenze; Decode-Gather mit vollständigen Blocktokens plus Rest; Rows-Gather mit gepaddeten Tailtokens und Gültigkeit; sonst vollständige kausale Maske. Flash gewinnt bei gleichzeitiger Aktivierung vor Decode-Gather. Gekachelte Scores schließen Rows-Gather wie im Original aus. Jede Kachel führt vor dem Anhängen der Indices ein echtes synchrones Eval aus; kein Ersatz durch Flush oder Async-Eval. Ungekachelte Auswahl und ungenutzte dichte Zwischen- ausdrücke bleiben verzögert. Die bestehenden Optionsfelder enthalten die vom Aufrufer aufgelöste Phase-/Positions-/Umgebungspolitik, nicht eine neue Heuristik allein anhand der Zeilenzahl. Bool/I64-GatherAxis verwendet jetzt alle vorhandenen Stride-/Adressierungs- varianten des Originaltemplates. Sieben zusätzliche Instanziierungen, keine geänderten Kernelkörper. Der Quellenabgleich bestätigt weiterhin17 Original- Metal-Körper und22 Runtime-Einheiten; die Runtime-Einstiegspunkte steigen von176 auf183. Alle vier Bool/I64-Row-Contiguity-Kombinationen einschließlich negativer Indices und negativer Source-/Index-Strides haben einen ausführbaren Check. Der gemeinsame `ops::repeat` übernimmt Expand/Broadcast/Reshape aus `ops.cpp` einschließlich Null-/Eins-/Fehlerfällen; auch die bestehende Blockmaskenrekonstruktion verwendet ihn statt eines duplizierten Ausdrucks. Die ursprünglichen Host-Lane-Zähler sind ebenfalls angeschlossen: `eager_selector`, `decode_flash_skip`, `decode_gather` und `decode_dense_mask`; Rows-Gather zählt wie das Original keinen dieser Zähler. Snapshot und optionaler Bericht bei Prozessende über `MTPLX_QSA_PREFILL_DEBUG` bleiben von GPU-Abschlussmessungen getrennt. 144 neue Receipts rufen direkt den gepinnten MTPLX-`QSAIndexer._select_eager` mit dem originalen QSACache auf:24 Profile × BF16/F16/F32 × TF32 on/off. Lazy und vorbereitete Rust-Ausführung ergeben420 bitgenaue Tensorvergleiche. Abgedeckt sind alle Ausgabeformen, echte Kachelgrenzen und deren Nichtaktivierung bei tile>=S, beide Gather-Schwellen, Flash-Priorität, Prefill-vs-Verify-Phase, partielle Tails, ungültige frühe Top-k-Slots, S2048, Kontext32768 sowie parametrisierte Ratio1/4/8. Der Test prüft Formen, Host-Tailwerte, Lane-Zähler und Kernelarbeit vor der Rückgabe: ausschließlich bei aktiven Score-Kacheln. Cache und Query werden vor dem abschließenden Eval freigegeben, sodass auch die Graph-Lebensdauer geprüft wird. Fixture: `tests/fixtures/mtplx-qsa-eager-graph.jsonl`, SHA256 `25ea1819857c0eb91ff6700298f597ba47ccebe418cc5259a1dde76aae7bca2b`. Der erste fokussierte TF32-on-Test besteht in1,78s; der gemeinsame TF32-off- Durchlauf mit unretained Command Buffers besteht125/125 Tests in74,83s. Dieser erste Gesamtlauf liegt vor den zusätzlichen Bool-Layout- und Lane-Zähler-Checks; deren finale Prüfung wird separat protokolliert. Finaler Stand: gemeinsamer Standard-TF32-Durchlauf125/125 in75,49s; TF32-off/FastSync-Auswahlprüfung1/1 in1,00s. Der Prozessabschluss meldet die erwarteten Lane-Zähler (42 eager_selector,18 decode_flash_skip, 12 decode_gather,6 decode_dense_mask). Release-Test-Clippy, Format-/Diff- und Quellenprüfung bestehen. Vollständige Protokolle: `local-eval-results/20260907-mtplx-port/eager-selection-graph-check.log`. Diese Testlaufzeiten sind keine Modell-Durchsatzwerte. Die finale TF32-off/unretained-Gruppe für Eager-Auswahl, Bool-Gather-Layouts und Repeat/Arraygraph besteht zusätzlich3/3 Tests in1,04s. P08 bleibt offen: vollständiger Indexer-Aufruf mit Projektion, Query-/Pooling- Vorbereitung und Cache-Update, Fused-/Compiled-Selektoren im kanonischen Graph und Attention-Aufruf. Die Eager-Auswahl ist verbunden und geprüft, nicht der gesamte Indexer und nicht das Produkt. Weiterhin `cfg(test)`; keine Vollmodell-Performance-, UI-Responsiveness- oder2%-Abnahme. ### Gemeinsamer QSA-Indexer-Vorlauf und fortlaufender Cache (2026-09-07) `qsa_indexer::Indexer::prepare_rows` verbindet jetzt den nicht-kompilierten gemeinsamen Vorlauf von `QSAIndexer._call_rows`: vorhandenes Dense-/Quantized- Linear oder direkt übergebene QK-Zeilen; Split/Reshape; Query-RMSNorm/RoPE; positionsbezogenes Schreiben der Rohschlüssel; Vervollständigen ganzer Pool- Blöcke, Norm/RoPE und Schreiben in gepoolten Cache samt F32-Spiegel. Die vorher geprüften Array-, Linear-, RoPE-, Reduktions-, Cache- und Custom- Kernel-Funktionen werden direkt wiederverwendet, keine zweite Mathematik. Query und Pool verwenden bei tatsächlich erfüllter Original-Eligibility die MTPLX-Prepare-Kernel; sonst den ursprünglichen Eager-Ausdruck. Pooling mittelt zuerst inF32, castet zurück zum Eingabetyp, normiert und rotiert danach. Blockpositionen stammen von `min(cache.pooled_len,total/ratio)`, nicht von der gerade gelieferten Chunkgrenze. Dadurch werden unvollständige Blöcke über mehrere Aufrufe korrekt vervollständigt und nach Rollback neu berechnet. Der Indexer verschiebt `kv.offset` nicht; das bleibt Aufgabe von Attention. Unterhalb/einschließlich des Blockbudgets erfolgt der originale Rücksprung nach den Cache-Updates. Die dabei ungenutzte Query-Vorbereitung bleibt ein verworfener Lazy-Ausdruck; der Test prüft ausdrücklich, dass ihr CustomKernel nicht trotzdem dispatcht wird. Oberhalb des Budgets werden Query, gepoolte Ansicht und Frontier an die bereits verbundene Eager-Auswahl weitergegeben. Fused-/Compiled-Auswahl wird dadurch nicht stillschweigend ersetzt. 306 neue Receipts benutzen den unveränderten ursprünglichen `QSAIndexer`- Aufruf und QSACache, mit kleinen lokalen Testgewichten und ohne Downloads: BF16/F16/F32, Dense und übergebene nicht-kontiguierliche QK-Zeilen, BF16-QuantizedLinear4/8bit, ganze/partielle RoPE, Prepare-Kernel an/aus, Originalfallback bei D256 bzw. abweichendem Norm-Dtype, TF32 on/off. Die Referenzflags wählen regulär Eager-Selection mit beiden Prepare-Pfaden; es werden keine Methoden ersetzt. Diese Fixturekonfiguration ist kein Produkt-Performance-Arm. Jedes Profil führt neun Aufrufe mit einem weiterbenutzten Cache aus: 3,1,5,2041,1,4 Tokens, dann fünf Tokens trimmen,8,33,1 Tokens. Das umfasst Blockvervollständigung, die512-Block-Schwelle, Cache-/Spiegelwachstum, Rewriting nach Trim, Rows-Gather, Dense und Decode-Gather. Verglichen werden vollständige Roh-/Pooling-/Spiegel-Backings inklusive Shape/Kapazität, Frontiers und Auswahl-Ausgaben. Lazy/vorbereitete Ausführung über beide TF32-Prozesse ergibt2.108 bitgenaue Tensorvergleiche. Beim ersten Rust-Vergleich wurden die physischen Bytes des transponierten F32-Spiegels als Row-Major gehasht. Roh- und Poolingcache stimmten bereits; der Fehler betraf nur die Test-Auslesereihenfolge. Der Fixture-Leser stellt jetzt wie NumPy `tobytes` die logische Reihenfolge her, ohne Cache- oder Modellberechnung zu ändern. Die unveränderten Referenzhashes bleiben Maßstab. Fixture: `tests/fixtures/mtplx-qsa-indexer-prefix.jsonl`, SHA256 `0f25280aab05b72158c7d596b67702c2bf67f2985bfa44fd9642430a14da5078`. Der fokussierte Standard-TF32-Vergleich besteht in2,76s. Prüfprotokoll: `local-eval-results/20260907-mtplx-port/indexer-prefix-check.log`. Finaler gemeinsamer Stand:126/126 Tests bei Standard-TF32 in76,36s, 126/126 bei TF32-off und unretained Command Buffers in78,51s. Die zusätzliche fokussierte FastSync-Sequenz besteht ebenfalls. Release-Test-Clippy, Format-/Diff- und unveränderte Quellenprüfung bestehen. Die genannten Prüfzeiten sind keine Inferenz-Performancewerte. P08 bleibt offen: kanonische Fused-/Compiled-Selektoren samt durchgängigem Routing und vollständiger Attention-Aufruf. `prepare_rows` ist kein Ersatz für diese offenen Routen und kein neuer Produktionsfallback. Der Port bleibt `cfg(test)`; die vollständige Produktmigration und Funktions-/Responsiveness-/2%-Performance-Abnahme sind weiterhin offen. ### Fused-QSA-Selektor im kanonischen Arraygraph (2026-09-07) `qsa_select` bildet nun den originalen `qsa_indexer_select_metal`-Aufruf als Mehrfachausgabe-Primitive ab: Block-IDs/Gültigkeit/Scores, Token-IDs/ Gültigkeit oder Dense-Maske, jeweils mit dem privaten F32-Score-Scratch als weiterem Graph-Sibling. Auswerten eines öffentlichen Ergebnisses führt den gemeinsamen Kernel genau einmal aus. Verwerfen der Eingabehandles vor Eval verliert weder Strides/Offsets noch dynamische Frontiers oder Scratch. BF16, F16 und F32 werden für Query und Pool unabhängig gebunden, ohne Kontiguierungs- oder Typkonvertierungsdispatch vor dem Originalkernel. Der Host baut dessen unveränderten Header/Körper/Epilog mit den originalen Formkonstanten und NAX/TF32-Bedingungen zusammen. Alle Ausgabepuffer werden wie beim originalen CustomKernel vor der Kompilierung angelegt. Ein gemeinsamer Encoder übernimmt Bindings, Datenumfänge, Grid und Threadgroup-Größe; auch die bisherige Buffer-Schnittstelle verwendet jetzt diesen Backendpfad. Es wurde keine zweite Implementierung desselben Shaders eingeführt. `Indexer::select_fused` übernimmt `_select_fused`: Query-Zeilen werden nach 32MiB Score-Scratch aufgeteilt, niemals die History. Dense-Ausgaben verwenden die stabile physische Breite `(backing_blocks+1)*ratio`; nach Concatenate folgt die logische Ansicht bis `total`. Zwischen den Chunks wurde kein zusätzliches Eval oder Flush eingeführt. 126 neue unveränderte Referenz-Receipts umfassen alle drei Ausgabeformen, BF16/F16/F32, gemischte Eingabedtypen, transponierte/gestridete/gebroadcastete Ansichten, Top-k1/3/7/512, Ratio1/3/4, verschiedene Headgeometrien, leere bzw. gepaddete History und eine echte 127+2-Zeilen-Aufteilung bei 65537 Backing-Blöcken. Für die Chunkfälle wird MTPLXs ursprüngliche `QSAIndexer._select_fused`-Methode mit ihrem ursprünglichen Chunkhelper aufgerufen; keine Ersatzmethoden. TF32 on/off und lazy/vorbereitete Eingaben, zusätzlich Host-/Tensor-Frontiers für direkte Aufrufe, ergeben936 bitgenaue Tensorvergleiche. Der Test prüft außerdem Sibling-Eigentümerschaft, verzögerte Konstruktion und die tatsächlich dispatchten Geometrien. Fixture: `tests/fixtures/mtplx-qsa-fused-graph.jsonl`, SHA256 `56d8b82dd8978ecd8ab0d69d918744668ce7bf596ac61815f5c5e9cd666f3b19`. Prüfprotokoll: `local-eval-results/20260907-mtplx-port/fused-selection-graph-check.log`. Der gemeinsame Stand besteht127/127 Tests bei Standard-TF32 in78,54s und127/127 bei TF32-off mit unretained Command Buffers in78,98s. Der fokussierte Fused-Graph-Test besteht zusätzlich mit FastSync, TF32-off und unretained Command Buffers in1,65s. Release-Test-Clippy sowie Format-/Diffprüfung bestehen. Die Quellenprüfung bestätigt weiterhin17 originale Körper,41 Custom-Entrypoints und22 Runtime- Einheiten mit183 Einträgen; an den Shaderdateien war keine Änderung nötig. Diese Testzeiten sind keine Modell-Inferenzmessung. P08 bleibt offen: kanonischer vektorisierter Prefill-Selektor und Compiled- Indexer, vollständiges Routing sowie Attention-Aufruf. Der neue Fused-Pfad ist kein Ersatz für diese anderen Originalrouten und wird nicht als allgemeiner Prefill-Fallback eingesetzt. Produktion bleibt unverändert auf dem alten Graphen (`qwen_mtplx` ist weiterhin `cfg(test)`). Deshalb sind Funktions-/Responsiveness-/2%-Performance-Parität des Gesamtmodells weiterhin nicht nachgewiesen; dieser Schritt hat keine Performance-Auswahl oder begründungslose Rücknahme eines MTPLX-Bestandteils vorgenommen. ### Zweistufiger Prefill-Selektor im kanonischen Arraygraph (2026-09-07) `qsa_prefill::select` verbindet jetzt den originalen `qsa_indexer_prefill_metal`-Graphen: statische Score-Produzentenwahl, produzentenabhängiges Workspace-/Alignment-Budget, Query-Slices, Scores, exakter Top-k-Selektor und Concatenate aller öffentlichen Ergebnisblätter. BF16/F16 mit gleicher Eingabedtype und H4/D128 verwenden bei originaler NAX-Eligibility den unveränderten TensorOps-Score-Kernel. Sonst wird der bereits geprüfte `attention::qsa_scores`-Ausdruck verwendet: F32-Matmul, ReLU pro Head, F32-Summe, Division. Der transponierte F32-Pool entsteht in dieser Route nur einmal und wird zwischen Chunks geteilt. Es gibt keinen Laufzeit-Fallback nach ausgewähltem TensorOps-Dispatch. Ein Fehler bleibt sichtbar. Score-Workspace zählt dort nur eine Ebene, beim allgemeinen Ausdruck H+1; große Teilchunks werden nach unten auf32 Zeilen ausgerichtet, eine irreduzible Zeile darf ein kleineres Budget überschreiten. Wie im Original kommt kein zusätzlicher Chunk-Eval/Flush hinzu. Beide neuen CustomKernel-Primitive teilen ihre Encoder mit den vorherigen Buffer-Aufrufern. Der Top-k-Quellgenerator ist nun Ratio-parametrisch statt auf4 festgelegt. Header/Körper/Epilog bleiben aus dem gepinnten Export. Top-k besitzt den ursprünglichen Mehrfachausgabe-Vertrag ohne zusätzlichen Scratch-Sibling. Der CustomKernel legt zuerst alle Ausgaben an, führt dann bei nicht-row-kontiguierlichen Eingaben die originale General-Copy aus und kompiliert/dispatcht anschließend. TensorOps konsumiert tatsächliche Strides und Offsets ohne solche impliziten Eingabekopien. Dynamische Frontiers bleiben im Graphen; auch `pos+row_start` wird nicht auf dem Host ausgelesen. 144 neue Receipts aus unveränderten MTPLX-Aufrufen prüfen BF16/F16/F32, gemischte Dtypes, Original-Fallbacks für andere Headgeometrien, transponierte/gestridete/gebroadcastete Eingaben, alle drei Ausgabeformen, kleinstes Workspace sowie produktionsnahe K512-/Ratio4-Geometrien. Der65-Zeilen-Fall erzwingt im TensorOps-Pfad32+32+1 Zeilen, im allgemeinen H4-Pfad8-Zeilen-Chunks plus Rest. Eigenständige Top-k-Fälle prüfen außerdem gestridete Scores und kleinere/mehrstufige Radix-Kandidatenmengen. TF32 on/off, lazy/vorbereitete Eingaben und Host-/Tensor-Frontiers ergeben 1.152 bitgenaue Tensorvergleiche. Tatsächliche Producer-/Top-k-Geometrien, Copy-Anzahl und verzögerte Konstruktion werden separat geprüft. Die erste neue Testassertion zählte Concatenate fälschlich als einen Dispatch; tatsächlich kopiert das Original jedes Chunk-Blatt einzeln. Nur diese Erwartung wurde korrigiert, keine Referenzhashes oder Shader. Der anfängliche33-Zeilen-Fall passte noch in einen Chunk und wurde für einen echten Alignment-/Restchunk-Nachweis mit65 Zeilen neu aufgenommen. Fixture: `tests/fixtures/mtplx-qsa-prefill-graph.jsonl`, SHA256 `f223b1157d13833e899fb1b73e35a5343f26fb48940ee3c908829df14f6ae289`. Prüfprotokoll: `local-eval-results/20260907-mtplx-port/prefill-selection-graph-check.log`. Der fokussierte Standard-TF32-Test besteht in2,17s; keine Inferenzzeit. Gemeinsamer Stand:128/128 Port-Tests bei Standard-TF32 in82,49s und 128/128 bei TF32-off mit unretained Command Buffers in80,25s bestanden. Der fokussierte Prefill-Test besteht zusätzlich mit FastSync, TF32-off und unretained Command Buffers in2,04s. Release-Test-Clippy, Format-/Diffprüfung und die unveränderte Quellenprüfung (17 Körper,41 Custom-Entrypoints,22 Runtime-Einheiten/183 Einträge) bestehen. Die ursprünglichen Shaderdateien benötigten keine Änderung. P08 bleibt offen: kanonischer Compiled-Indexer, vollständige Verbindung der vorhandenen Selektoren mit Indexer-Routing und Attention, Full-SDPA sowie Produktmigration. Der gesamte neue Graph bleibt `cfg(test)`. Es wurde kein Produkt-Performance-/Responsiveness-Pass aus diesen Kernelprüfungen abgeleitet. ### Dynamische Cache-Fenster im kanonischen Arraygraph (2026-09-07) Die noch fehlenden `DynamicSlice`/`DynamicSliceUpdate`-Operationen des Compiled-Indexer-Graphen sind nun im gemeinsamen Array-/Eval-Pfad vorhanden. Achsenprüfung, Broadcast/Cast des Updates, leere Ergebnisse/Updates, Copy-/Donation-Auswahl und dynamische Geräteoffsets folgen dem gepinnten Runtime-Original. Die Updates benutzen denselben General/GeneralGeneral- Copy-Encoder wie statische Operationen, mit den ursprünglichen dynamischen Runtime-Kerneleinträgen. Es kommen weder Host-Readback der Position noch zusätzlicher Eval/Flush oder eine Ersatzimplementierung des Indexers hinzu. Die Offset-Berechnung verwendet den erfassten ursprünglichen Shaderkörper mit den originalen acht Integer-Typinstanziierungen. Auch die bisherigen Buffer-basierten Cache-Aufrufer verwenden jetzt diesen gemeinsamen Encoder; deren doppelte Offset-Implementierung ist entfernt. Originales Last-use-Donation kann Metadaten des Indexpuffers unverändert an den internen int64-Offset weitergeben, einschließlich abweichender Dtype, Scalar-Rank und `data_size`. Dafür gibt es die originale unqualifizierte `copy_shared_buffer`-Variante; die vorhandene explizite View-Prüfung bleibt unverändert. Physische Zugriffsgrenzen werden weiterhin geprüft. Beim Ergänzen des Donation-Tests fiel im Quellvergleich eine fehlende Output-Byteoffset-Bindung auf; sie ist korrigiert. Tests mit Offset 0/8 prüfen auch, dass vorangestellte Sentinel-Bytes unverändert bleiben. 30 Fälle aus unveränderten Referenzaufrufen liefern 360 bitgenaue Tensorvergleiche: BF16/F16/F32, acht Integer-Indextypen, lazy/vorbereitete Eingaben, behaltene/freigegebene Quellen, Transpose/Stride/Broadcast/negative Strides, mehrere Achsen, leere und skalare Updates sowie verkettete Cache-Fenster. Zusätzlich werden Dispatch-Anzahl, verzögerte Konstruktion und gemeinsame beziehungsweise getrennte Pufferidentität geprüft. Fixture: `tests/fixtures/mtplx-dynamic-slice-graph.jsonl`, SHA256 `86d170991c68c9009b10eeead9479bc575e89b7eef6528e2a39677220d218acc`. Gemeinsame Regression: 129/129 Port-Tests bestehen mit Standard-TF32 (80,93 s) und mit TF32-off/unretained Command Buffers (81,71 s). Der fokussierte neue Test besteht zusätzlich mit FastSync (0,81 s). Release-Test-Clippy, Format-/Diffprüfung und die unveränderte Quellenprüfung (17 Körper, 41 Custom-Entrypoints, 22 Runtime-Einheiten/183 Einträge) bestehen. Protokoll: `local-eval-results/20260907-mtplx-port/dynamic-slice-graph-check.log`. Dies sind Testlaufzeiten, keine Inferenz-Leistungsdaten. P08 bleibt offen: Dies schließt eine Abhängigkeit des kanonischen Compiled- Indexers, nicht dessen Graphbank/Replay und Routing. Full-SDPA, vollständiger Attention-Aufruf und Produktmigration bleiben erforderlich. Weiterhin `cfg(test)`; kein Gesamtmodell-, UI- oder Performance-Paritätsnachweis. ### Reiner Compiled-Indexer und kanonisches Graph-Replay (2026-09-07) `qsa_compile::Body` verbindet nun die reine zehnargumentige Grenze von `QSACompiledIndexerCore`: bereits projizierte Q/K-Zeilen oder interne Projektion, explizite Norm-/RoPE-Eingänge, dynamische Raw-/Pool-Updates, begrenztes rückwärtiges Pool-Fenster, Query-Vorbereitung und alle fünf Ausgabeformen. Die vier State-Ergebnisse bleiben Array-Ausgänge; Position und logische Blockzahl werden unverändert als Eingangsdescriptoren zurückgegeben. Der Body mutiert keinen Host-Cache und liest keine Frontiers auf dem Host aus. `compiled::Replay` übernimmt die feste DFS-/Sibling-Tape-Struktur und `compile_replace`-Semantik: einmalige Tracer-Platzhalter, danach neue Ausgabe-Descriptoren mit gemeinsamem unveränderlichem Primitiv und jeweils aktuellen Eingangsarrays. Konstanten/Load-Blätter bleiben geteilt, Shapes und Dtypes sind fest, Strides/Offsets und Werte keine Trace-Konstanten. Die Konstruktion und das Replay dispatchen keine GPU-Arbeit. Ein eigener Hosttest prüft vertauschte Sibling-Root-Reihenfolge, Descriptor-/Primitiv- Identität, neue Eingänge sowie Fehler für falsche Signaturen und unzulässig geschlossene ursprüngliche Aufrufseingänge. Die Clamp-/Multiply-/Chunk-Position-Knoten verwenden die unverändert erfassten fusionierten Compiled-Shader, keine Reihe einzelner Binary-Kernel. Sie teilen den bereits vorhandenen Compiled-Evaluator einschließlich Layout-/Donation-Auswahl. Auch die vorherigen Buffer-Aufrufer benutzen jetzt diesen Backendpfad; drei doppelte Skalar-Encoder sind entfernt. Quellgenerierung und JSON-Auswertung geschehen nur beim ersten Compile, nicht bei jedem Decode-Schritt. Der Prefill-Body teilt den bisherigen Zweistufen-Selektor; im Compiled-Aufruf ist die Chunk-Position ebenfalls der originale fusionierte Add-Knoten. 198 bestehende unveränderte Referenzfälle prüfen Q/K und vier affine Hidden-Projektionsvarianten (4/8 Bit, Gruppen32/64), alle fünf Modi, Zeilenzahlen1/4/5/33/65/2048, zwei Scratch-Budgets sowie wechselnde Q/K-Strides640/704. Ausgaben, neue/alte Cache-Hashes und die aus dem Original-DOT abgeleiteten geordneten Abhängigkeits-/Sibling-Fingerprints stimmen überein. Die Testbank verwendet bei Stride-Wechseln denselben Replay-Eintrag; sie ist nicht die noch ausstehende produktive Host-Graphbank. Die Referenzfälle sind BF16/H4/D128, Prefill verwendet MPP auf diesem M5 Max. Der Test führt diese Fälle anschließend jeweils mit behaltenen und ohne behaltene Cache-Snapshots aus: 396 Replays und 2.052 Tensor-/Cache-Hashes. Mit Snapshot müssen alte Zustände unverändert bleiben und neue Backings entstehen; ohne Snapshot müssen Raw- und Pool-Ausgabe die ursprüngliche Data-Identität wiederverwenden. Die Graphbank selbst hält keine alten Aufrufseingänge und verhindert diese Donation nicht. 131/131 gemeinsame Port-Tests bestehen bei Standard-TF32 (80,79 s; vor Erweiterung des neuen Tests auf beide Snapshot-Varianten) und bei TF32-off mit unretained Command Buffers (82,09 s; alle 396 Replays). Die 396 Replays bestehen zusätzlich bei Standard-TF32 mit FastSync (1,33 s). Release-Test-Clippy, Format-/Diffprüfung und die unveränderte Quellenprüfung (17 Körper, 41 Custom-Entrypoints, 22 Runtime-Einheiten/183 Einträge) bestehen. Protokoll: `local-eval-results/20260907-mtplx-port/compiled-indexer-replay-check.log`. Dies sind Testlaufzeiten, keine Modell-Inferenzmessungen. P08 bleibt offen: der Host-Core mit Bucket-/Frontier-Validierung, vollständigen Compile-Schlüsseln, Engagement-Statistik und Indexer-Routing; außerdem weitere Compiled-Geometrien/Dtypes einschließlich der allgemeinen Nicht-MPP-Score-Fusion, Full-SDPA, Attention und Produktmigration. Replay ist ausdrücklich kein allgemeiner Ersatz für die ursprünglichen Compiler-Simplify-/Fuse-Pässe. Deren Wirkung ist für die oben genannten erfassten Graphen nachgewiesen, nicht pauschal für beliebige Ausdrücke. Weiterhin `cfg(test)`, keine Modell-/UI-/2%-Performance-Abnahme. ### Kanonischer Compiled-Host-Core und Engagement (2026-09-07) `qsa_core::Core` implementiert nun zusätzlich zum reinen Replay-Test den Host-Vertrag von `QSACompiledIndexerCore`: unveränderliche Konfiguration, Norm-/RoPE-Eingänge, optionale interne Projektion und getrennte Hidden-/QK- Schlüssel. Sämtliche Shape-/Dtype-/Head-/Top-k-/Ratio-/Dense-Capacity-/Producer- und Chunk-Felder des ursprünglichen `_CompileKey` werden berücksichtigt. Werte, Strides und Offsets sind weiterhin keine zusätzlichen Schlüssel. Die ursprüngliche Standardkonfiguration und benutzerdefinierte Bucket- Untergrenzen sowie die abschaltbare Bucket-Pflicht bleiben erhalten. Der Core prüft Projektions-/Cache-/Norm-Dtypes, Backing-Geometrien, feste Pool-Fenster, Host-Frontiers und Backing-sichere Dense-Ausgabebreiten vor dem Dispatch. Tensor-Frontiers werden lediglich auf ein int32[1]-Array normalisiert, nicht synchron auf dem Host ausgelesen. Die Rückgabe trennt Auswahl und vier explizite State-Blätter. Host-Cache-Commit und Aufrufroutenauswahl liegen weiterhin beim noch anzuschließenden Indexer. Calls, Source-/Mode-/Producer-Zähler, Selector-Dispatches, Capacity-Transitions, Bucket-Zähler und vollständig sortierte Compile-Key-Berichte folgen dem Original. Ein nach erstem Trace-Fehler leerer Laufzeit-Eintrag bleibt im Host-Core bestehen: Wiederaufruf versucht den Trace erneut, ohne einen zweiten Core-Trace-Request zu zählen oder einen halb aufgebauten Replay zu verwenden. Bereits als Tracer übergebene Arrays bauen wie im Original direkt den Body, statt den gecachten Replay zu verwenden. Kein Eager-Fehlerfallback wurde ergänzt. 32 neue Receipts wurden mit unverändertem MTPLX-Core aufgenommen: elf echte aufeinanderfolgende Aufrufe mit wechselnden Shapes, Strides, Positionen, Kapazitäten, Hidden-/QK-Quellen und allen fünf Modi (66 bitgenaue Output-/State- Hashes), vollständige Zwischen-/Endberichte, 17 Validierungsfälle und zwei aufeinanderfolgende fehlgeschlagene Erst-Traces. Der zulässige Tensor-Frontier- Fall wird nur lazy aufgebaut und ausdrücklich nicht auf der GPU ausgeführt; sein Host-Gegenstück wird vorher abgewiesen. Neun zusätzliche Konstruktor- Assertions sichern die direkt aus dem Quellcode portierten Grenzen ab. Fixture: `tests/fixtures/mtplx-qsa-core-host.jsonl`, SHA256 `05d3642cbf08a12f6f1c1ad7cac0b529d2ef51f3bfb9c27ab6ab229aa1017022`. Der fokussierte Referenztest besteht (0,75 s; keine Inferenzzeit). Gemeinsame Regression: 132/132 Port-Tests bei Standard-TF32 (82,51 s) und TF32-off/unretained Command Buffers (82,61 s); fokussierter Host-Core mit FastSync ebenfalls bestanden (0,07 s). Release-Test-Clippy, Format-/Diff- prüfung und unveränderte Quellenprüfung (17 Körper, 41 Custom-Entrypoints, 22 Runtime-Einheiten/183 Einträge) bestehen. Protokoll: `local-eval-results/20260907-mtplx-port/compiled-host-core-check.log`. Die Laufzeiten sind keine Modell-Performance-Abnahme. P08 bleibt offen: Parameter-Identitätssiegel und Core-Lebenszyklus im Indexer, automatische Backing-Reservierung/Commit, vollständiges Fused-/Eager-/Compiled- Routing, übrige Compiled-Geometrien/Dtypes und Nicht-MPP-Score-Fusion, Full-SDPA, Attention und Produktmigration. Der Host-Core ist noch nicht der vollständig verbundene Modellaufruf; weiterhin `cfg(test)` und keine Modell-/UI-/2%-Performance-Abnahme. ### Durchgehender kanonischer Indexer und Cache-Commit (2026-09-07) `qsa_indexer::Indexer` verbindet jetzt den gemeinsamen Vorlauf, den persistenten Compiled-Core sowie Compiled-/Prefill-/Fused-/Eager-Routing in einem Aufruf. Die ursprünglichen Phase-/Shape-/Dtype-/Projektions-/Cache-Prüfungen entscheiden vor der Reservierung; Dispatchfehler führen nicht zu einem Eager-Wiederanlauf. Die vorhandene Modusregel wird auch vom alten Buffer-Aufrufer verwendet und nimmt nun Ratio/Top-k explizit entgegen, statt die Modellgeometrie festzusetzen. Die bereits geprüften Selektoren, Cache-Operationen und Engagement-Zähler werden gemeinsam genutzt. Es gibt keinen zusätzlichen Flush, Wait oder Readback im Compiled-Aufruf; ursprüngliche Eager-Kachel-Evals bleiben unverändert. Das Identitätssiegel erfasst Normen, Frequenzen und Projektionsgewicht sowie Quantisierungsskalen/-biases. Ein ausgetauschtes Blatt baut den Core neu auf; gleiche Bytes genügen nicht zum Wiederverwenden. Unveränderte Blätter behalten den Core und dessen ursprünglich erfasste Speicherbudgets. Fehlgeschlagene Neukonstruktion lässt den bisherigen Core samt Siegel bestehen. Backings werden vor dem Core-Aufruf reserviert; dessen explizite Ergebnisse ersetzen die Cache-Arrayobjekte, aktualisieren die logische Pool-Länge und verwerfen den F32-Spiegel. Alte Snapshots bleiben unverändert. `cache.kv.offset` wird nicht vorweggenommen; dessen Fortschreibung gehört weiterhin zu Attention. 26 neue, unveränderte MTPLX-Aufrufe prüfen fortlaufend alle fünf Rückgabeformen, Hidden-/QK-Quellen, dichte/quantisierte Projektion, Gewichtswechsel, Budget- Wiederverwendung, Backing-Wachstum, Trim und gescheiterte Core-Ersetzung. 52 Rust-Aufrufe mit/ohne gehaltene Snapshots stimmen in 216 Output-/State- Hashvergleichen überein; vollständige Core-Berichte stimmen ebenfalls. Fixture: `tests/fixtures/mtplx-qsa-indexer-commit.jsonl`, SHA256 `ed4dde278663e0f7d684fc78ea51474f68ab5326f467f3022ef521a7cf93939e`. Zusätzlich stimmen die 200 vorhandenen vollständigen Indexer-Referenzaufrufe einschließlich 2K-Prefill, aller Lane-Wechsel, Cache-Inhalte und Graphbank-Zähler mit dem kanonischen Arraygraph überein. Die 720 vorhandenen statischen Zulässigkeitsfälle stimmen ohne GPU-Dispatch überein, einschließlich inkonsistenter Frontiers und nicht gebucketeter/leer vorhandener Backings. Diese Nachweise betreffen die erfasste B1/BF16/H4/D128-Modellgeometrie, nicht beliebige Typen. Gemeinsame Regression: 134/134 bei Standard-TF32 (84,69 s; vor Ergänzung der 720 statischen Assertions) und TF32-off/unretained Command Buffers (84,18 s; einschließlich dieser Assertions). Die drei Indexer-Tests bestehen außerdem bei Standard-TF32 mit FastSync (3,36 s), ebenfalls einschließlich aller 720 Assertions. Release-Test-Clippy, Format-/Diffprüfung und die unveränderte Quellenprüfung (17 Körper, 41 Custom-Entrypoints, 22 Runtime-Einheiten/183 Einträge) bestehen. Protokoll: `local-eval-results/20260907-mtplx-port/indexer-lifecycle-routing-check.log`. Diese Laufzeiten sind Korrektheitstestzeiten, keine Inferenzmessungen. P08 bleibt offen für übrige Compiled-Geometrien/Dtypes einschließlich der allgemeinen Nicht-MPP-Score-Fusion, Full-SDPA, den vollständigen Attention-Aufruf und die Produktmigration. Der Port bleibt `cfg(test)`; die alte UI-Ausführung ist damit noch nicht ersetzt und das 2%-Gesamtziel bleibt offen. ### Verbundener Qwen-Attention-Modulaufruf (2026-09-08) `qsa_attention::Attention` verbindet nun den vollständigen BF16/D256-Aufruf der MTPLX-Klasse: separate Q/K/V-Projektionen oder gemeinsame Drei-/Vierfach- Projektion, Indexer vor KV-Fortschreibung, per-Head-Norm, Query-/Gate-Aufteilung, partielles RoPE/M-RoPE, KV-Update, sämtliche QSA-Consumer, Sigmoid-Ausgangsgate und Ausgangsprojektion. Biased separate Projektionen sowie fehlender Indexer sind ebenfalls abgebildet. Die bereits geprüften Operationen/Kernel werden verwendet, nicht neu implementiert. Ein beim Anschluss geschlossener Referenzunterschied: Die originale Vierfachfusion entfernt `indexer.index_qk_proj`. `Indexer::projection` ist deshalb jetzt optional. Zugelieferte QK-Zeilen funktionieren ohne diese Projektion; das Identitätssiegel enthält dann nur Normen/Frequenzen und der Compiled-Core erfasst keine versteckte zweite Projektion. Ein Hidden-Aufruf ohne Projektion wird nicht durch einen erfundenen Ersatz bedient. Die Consumer-Reihenfolge bleibt Flash-Skip, Prefill-Flash, optionaler Prefill-Gather, Dense-Rekonstruktion, Rows-Gather und gewöhnliches SDPA. Sparse-Flash liest die KV-Backings und ihre Kapazitätsstrides direkt. Die ursprünglichen Engagement-Zähler und die expliziten Gather-Tile-Evals bleiben erhalten; es gibt keine zusätzliche Aufmerksamkeitssynchronisation. Ein Vision-Request überspringt nur die Sparse-Auswahl, nicht den Indexer und seine Cache-Updates. M-RoPE verwendet innerhalb der Tabelle deren Achsen; danach die normale Positionsfolge mit Request-Delta. Ohne konfigurierte M-RoPE-Achsen bleibt das originale Plain-RoPE-Verhalten erhalten. **Keine stillschweigende Full-SDPA-Abkürzung:** Qwens normaler D256-Aufruf verwendet eine explizite Array-Maske oder keine Maske. Die gepinnte Runtime selektiert hier für S>8 den Matmul-Fallback. Der NAX-D256-Split wird dagegen nur für kausale String-Maske ohne Array-Maske und S>=1024 gewählt (`scaled_dot_product_attention.cpp:750–767`). Der Modellport behält diese Originalauswahl; die allgemeine Full-SDPA-Erweiterung bleibt separat offen. 56 Receipts stammen aus der unveränderten MTPLX-Attention-Klasse, je 28 mit TF32 an/aus. Zehn fortlaufende Szenarien umfassen kalten 2K-Prefill, Prefill ab 32768 mit ursprünglichem Sparse-Flash, Decode/Verify, alle Consumer, Cache-Trim, Projektionsfusion mit wirklich entfernter Indexer-Projektion, Bias/no-indexer und Vision inklusive des ersten Schritts nach dem Tabellenende. Die Referenz protokolliert die tatsächlich aufgerufenen Consumer durch reine weiterleitende Beobachter; keine Berechnung wird ersetzt. 288 Referenzhashes decken Ausgabe und KV-/Raw-/Pool-/F32-Mirror-Backings ab. Rust prüft zusätzlich Shapes, Frontiers, vollständige Core-Berichte, Engagement-Deltas und die tatsächlichen Sparse-Flash-Graphknoten/-Dispatches. Fixture: `tests/fixtures/mtplx-qsa-attention-module.jsonl`, SHA256 `d0fdbd1ad13820004a672a7634e50a66cf50a708180a9d037720920619f02016`. 112 Rust-Aufrufe (jeweils lazy/vorbereitet, TF32 an/aus) bestehen mit 576 bitgenauen Ausgabe-/Cache-Hashvergleichen. Gemeinsame Regression135/135 bei Standard-TF32 (120,88 s) und TF32-off/unretained Command Buffers (121,01 s); vollständiger Attention-FastSync-Test ebenfalls bestanden (1,34 s). Release-Test-Clippy, Format-/Diffprüfung und unveränderte Quellenprüfung (17 Körper,41 Custom-Entrypoints,22 Runtime-Einheiten/183 Einträge) bestehen. Die Testlaufzeiten sind keine Modell-Performancewerte. Protokoll: `local-eval-results/20260908-mtplx-port/attention-module-check.log`. Der vollständige Modell-/Decoder-/Serving-Aufruf und die Produktionsumstellung bleiben offen, ebenso andere SDPA-Dtypes/Geometrien und übrige Compiled- Geometrien/Nicht-MPP-Score-Fusion. `cfg(test)` ist weiterhin aktiv; dies ist weder eine UI-Responsivitäts- noch eine Gesamtperformance-Abnahme. Aktuelle Reproduktionsbefehle für die Kernel-Korrektheit: ```sh python3 tools/mtplx-kernel-source.py local-eval-results/mtplx-reference-e652d55 --gated-delta-source local-eval-results/mtplx-reference-env-0.32.2/lib/python3.12/site-packages/mlx_lm/models/gated_delta.py --check cargo test --release mtplx_canonical_source_bodies_preserve_pinned_hashes -- --nocapture cargo test --release mtplx_canonical_hyper_and_gdn_kernels_match_reference -- --ignored --nocapture --test-threads=1 cargo test --release qwen_mtplx -- --include-ignored --test-threads=1 ``` ## Auftrag und Grenzen Qwen muss funktional und hinsichtlich Durchsatz und Verzögerungen dem tatsächlich aktivierten MTPLX-Pfad entsprechen oder schneller sein. Die Referenzzuordnung ist verbindlich und gilt auch für spekulatives Decoding: | Modell | Golden Master | Andere Implementierungen | | --- | --- | --- | | DeepSeek V4 Flash | antirez/ds4, einschließlich DSpark | MTPLX nur als zusätzliche Optimierungsquelle | | GLM 5.3 Flash | antirez/ds4, einschließlich integriertem MTP | MTPLX nur als zusätzliche Optimierungsquelle | | Qwen3.8 Flash Next | MTPLX | DS4 nur für gemeinsame Infrastrukturideen, nicht als Qwen-Orakel | Ein möglicherweise besserer MTPLX-Ansatz für DeepSeek/GLM ersetzt deren Golden Master nicht. Verbesserungen müssen die antirez/ds4-Verhaltens- und Sampling- Verträge erhalten; eine abweichende Semantik braucht vor Umsetzung eine ausdrückliche Nutzerentscheidung. Die UI und die Headless-Harness müssen dieselbe Produkt-Inferenz ausführen. Ein kleinerer Qwen-Prefill-Chunk, niedrigere Leistung oder zusätzliche Wartezeiten sind kein Ersatz für Ursachenklärung. Dieser Abgleich inventarisiert die Ausführungskette und ordnet belegte Unterschiede, bereits korrigierte Fehler und noch fehlende Nachweise ein. Er behauptet **nicht**, dass jede numerische Operation und jeder seltene Fallback bereits als identisch bewiesen ist. Diese offenen Nachweise haben unten eigene Tasks mit Abnahmekriterien. Für die weitere Umsetzung gilt die verbindliche Auftragspräzisierung oben. Nur vorhandene Modelle; keine Downloads. Keine neuen Projekt-Gates, externen Issues oder Codex-Tasks. Die folgende Liste ist die lokale Arbeitsquelle. Bestehende ungecommittete Änderungen bleiben erhalten. ## Festgehaltene Referenzen und Belege - DS4Server: Arbeitsbaum auf `b99ce2a`, inklusive ungecommittierter Änderungen. - MTPLX: `local-eval-results/mtplx-reference-e652d55`, Commit `e652d55e2652137a4abcf1312357abbf3eb9d692`, installierte Runtime0.32.2. Am2026-09-06 identisch wiederhergestellt, nachdem im früheren temporären Checkout `/private/tmp/MTPLX-analysis-20260901` Quelldateien fehlten. - DS4: `/Users/gb/Projects/ds4`, Commit `ec7642cdd9ec81d01ad4b1fd8f8a3d1511533748`. C-Code nur lesen, nicht in DS4Server übernehmen, kompilieren oder als Inferenz-Backend aufrufen. - Qwen: vorhandenes Bare-Speed-Artefakt unter `/Users/gb/Library/Application Support/de.rfc1437.ds4server/models/qwen3.8-flash-next`. - Messbelege und Methoden: [Qwen-Responsiveness-Bericht](/Users/gb/Projects/DS4Server/docs/qwen-reference-responsiveness-20260905.md). Rohdaten: `/private/tmp/ds4-ongoing-verified.16vzVw/`. Der wiederholte MTPLX-AR-Lauf mit expliziter Session hatte maximal **2,974 ms** GPU-Canary-Completion im Prefill, MTPLX-MTP **0,550 ms**. DS4Server-AR hatte **4090,027 ms**. Gleiche native Probe, im jeweiligen Inferenzprozess; keine fehlgeschlagenen Probes. Das belegt eine reale Responsiveness-Differenz, aber noch nicht deren vollständige Aufteilung auf Scheduling und einzelne Kernel. Die bisherigen Durchsatzwerte sind keine saubere 2%-Abnahme: Tokenisierung und Cache-Wiederverwendung unterscheiden sich, die Canary war aktiv, und es fehlt eine wiederholte, vollständig normalisierte Sechs-Zellen-Matrix. Historische GLM-MTP-Daten mit überlappenden Workern sind ungültig. ### Tatsächlich aktive Qwen-Referenz statt allgemeiner MLX-Defaults Die `/health`-Receipts in `mtplx-ar-session.jsonl` und `mtplx-mtp.jsonl` belegen: Turbo, Chunk 2048, Kontextkapazität 131072, Low, Temperatur 1, top-p 0,95, top-k 20, Seed 12345; committed MTP history, batched verify, `linear-gdn-from-conv-tape`, lazy target distributions, family capture commit. Fused HC V3, GDN input/step/convnorm, verify convnorm und gate/up sind aktiviert. **NAX verify ist für diese Familie deaktiviert**, trotz des generischen Turbo-Profils. Aktiviertes Environment allein beweist noch keinen Kernel-Aufruf; Form- und Gerätegrenzen müssen ebenfalls passen. Die Referenz lädt den MTP-Kopf auch beim AR-Server. Ihr Ready-Receipt zeigt noch laufende Background-Warmup-Schritte. DS4Server lädt den Kopf bei abgeschaltetem MTP nicht und die Harness führt einen eigenen separaten Warmup aus. Ladezeit, Speicherbedarf und Kaltstart dürfen deshalb noch nicht direkt gleichgesetzt werden. ### Veröffentlichte M5-Max-Zahlen: Orientierung, keine Ersatzmessung Der lokal gepinnte MTPLX-Releasebericht [2.10.0](/private/tmp/MTPLX-analysis-20260901/docs/releases/v2.10.0.md:21) nennt für Flash-Next 61 tok/s AR und 63–76 tok/s MTP je nach Workload. [2.10.1](/private/tmp/MTPLX-analysis-20260901/docs/releases/v2.10.1.md:5) nennt für lange Prefills 175,7 → 114,5 s bei 98k Tokens und 810 tok/s bei 131k. Diese Angaben sind keine Referenz für einen beliebigen kurzen Summary-/Story-Chat. Die Online-Abfrage der gepinnten MTPLX-Dateien war nicht abrufbar; die Zahlen sind aus dem aktuell lokal geprüften Referenzcheckout, nicht als online neu bestätigt ausgegeben. Der [DS4-Speedabschnitt](https://github.com/antirez/ds4#speed) beschreibt dagegen 2048-Token-Schritte und 128 greedy Tokens mit *Promessi sposi*. Im lokalen Pin stehen bei Kontext 2048 rund 790,18 Prefill- und 39,35 Decode-tok/s. Das ist eine andere Arbeit als drei freie Antworten bis EOS. Nicht vermischen. ## Abdeckungsmatrix der Ausführungskette Status: **M** gemessen; **Q** Unterschied im Quellcode belegt, Kosten/Tragweite noch nicht vollständig gemessen; **T** Teilnachweis vorhanden; **O** Nachweis offen. Quellstellen beziehen sich auf den oben genannten Arbeitsstand. | Bereich | DS4Server | Referenz / Befund | Status / Task | | --- | --- | --- | --- | | Frontend → Engine | `src/app/generation.rs:780`, `src/model_eval.rs:803`, `src/runtime.rs:108` | Gleicher `GenerationService`, eigener `model-runtime`-Thread, LocalChat. Harness hat keinen echten GUI-Eventloop und bildet nicht jede UI-Nebenarbeit ab. | T/Q · P02, P04 | | Systemprompt / Tools / Skills | `src/app/generation.rs:2469` | Headless-Helper lädt ExtensionRegistry und hängt verfügbare Skill-Instruktionen an. Kein Beleg für ausgeführte Tools, aber noch kein sauber isolierter Test ohne deren Prompt-Anteile. | Q · P02 | | Qwen-Chatfortsetzung | `src/engine/tokenizer.rs:524`, `src/engine.rs:1420` | Zusätzliche Low-Systemnachricht bei Checkpoint-Fortsetzung erzeugte 30 zusätzliche Tokens. Lokal korrigiert und Regressionstest bestanden; End-to-end-Vergleich noch offen. | M/T · P02 | | Cache / ongoing Chat | `src/engine/metal/qwen.rs:5312`, `src/model_eval.rs:907` | MTPLX AR wiederverwendete jedes Mal 5120 Tokens; MTP 5120/7840/8861. Vollständige History ist nicht gleich identischer Cache-Arbeit. | M · P03 | | Laden / Warmup / Speicher | `src/engine/qwen.rs:362`, `src/engine/metal/qwen.rs:409` | Volle Kontextpuffer, andere Aktivierungs-Speichertypen; Referenz mit MTP-Kopf und Background-Warmup. | Q/O · P01, P09, P15 | | Command-Buffer-Scheduling | `src/engine/metal/qwen.rs:844`, `native/metal/ds4_metal.m:11878` | Qwen bei 100% ein CB über alle Prefill-Layer. MLX automatische asynchrone Commit-Grenzen nach Operationen/Bytes. | M/Q · P05 | | PLE-Hash / Gather / SSD | `src/engine/qwen.rs:224`, `src/engine/metal/qwen.rs:1024` | Beide 16 Leser und nominell 1 GiB Hot Rows. MTPLX staged vor Graphaufbau, große Gathers umgehen Row-LRU; Rust liest bei Layer 1 und cached auch große Gathers. | T/Q · P10 | | HC / Normalisierung | `src/engine/metal/qwen.rs:1247`, `metal/qwen38.metal` | MTPLX `GatedResidual` und `hc_read_v3`; Formgrenzen, Fusions- und Rundungsstellen nicht lückenlos durchgetestet. | T/O · P09 | | GDN Prefill / Decode / Verify | `src/engine/metal/qwen.rs`, `encode_gdn_conv_norm_rows` | Große Conv/Norm-Prefills nun zeilenparallel mit referenzgleichen BF16-Grenzen; modellfreier Boundary-Test exakt. Delta-Threadgeometrie und vollständige Layer-/State-Parität weiter offen. | T/M · P06 | | Router / MoE / Shared Expert | `src/engine/metal/qwen.rs:2738`, `:2826`, `:2919` | Rust sortiert ab S=5, MTPLX bei ≥64 Routen (bei top-10 ab S=7). Rust Prefill gate/up getrennt, aktive MTPLX-Fusionsklasse gemeinsam. | Q/T · P07 | | QSA / KV / FlashAttention | `src/engine/metal/qwen.rs:2134`, `:2551` | Rust baut dichte KV-Stagingansichten erneut auf; F16-Flash-Staging versus BF16-Referenzpfad. Sparse-Grenzen und tatsächliche Kernel prüfen. | Q/T · P08 | | QMV / QMM / Quantisierung | `src/engine/metal/qwen.rs:3178`, `metal/qwen38.metal` | Frühere logische Output-Länge/BF16-Rundung korrigiert. Golden-Test gilt für geprüfte Formen, nicht alle Matmuls. | T · P09 | | MTP Draft / Verteilung | `src/engine/metal/qwen.rs:4428`, `:4894` | Rust D3 fest, Referenz unterstützt D1..D5 (Default D3); Rust berechnet Target-Verteilungen für gesamten Verify-Block, MTPLX lazy entlang Acceptance-Pfad. | Q · P11 | | MTP Commit / Repair / EOS | `src/engine/metal/qwen.rs:4735` | Rust kann gesamten Kontext scalar replayen; Referenz captured-prefix commit / begrenzte Repair-Pfade. Pending-/EOS-/Cancel-Zustände vollständig prüfen. | Q/T · P12 | | DeepSeek DSpark | `src/settings.rs`, `src/engine/metal.rs` | Default Confidence war 0,8 statt DS4 Metal 0,6. Jetzt lokal korrigiert, einschließlich temperaturabhängigem Exact-Default; End-to-end-Messung offen. | Q/T · P13 | | GLM MTP | `src/engine/metal/glm.rs:1788`, `src/engine/metal.rs:4531` | Rust akzeptiert über einzelne Target-Forwards, DS4 verifiziert kompatibles Paar im 2-Row-Batch. Sampled Dispatch ist opportunistisch, nicht exact. | Q · P14 | | DS/GLM Prefill / Power | `src/engine/metal.rs:3910`, `src/engine/metal/glm.rs:4596` | DS4 hat echte Keepalive-Commit-Grenzen; GLM-Rust Flush hängt an `read_logits && rows>8`, Referenz zusätzlich an Progress-/Stage-/Kontextbedingungen. | Q/O · P15 | | Metriken / Abschluss | `src/model_eval.rs:327`, `src/app.rs:1354`, `native/metal/ds4_metal.m:1041` | Gleiche native Probe, andere Host-Einbettung. Verifier-Zeit überlappt Repair; Prefill-Zähler nicht referenzgleich; Canary/Profiling können Messung verändern. | M/Q · P04, P16 | ## Priorisierte Tasks Für Qwen ist eine Abweichung von der geforderten Kernel-/Funktionsidentität ein offener Portierungsbestandteil, unabhängig vom isolierten Geschwindigkeitswert. Kein Task wird allein durch einen plausiblen Textoutput oder einen einzelnen schnelleren Lauf geschlossen. ### P01 — Reproduzierbare Ausgangslage sichern Priorität P0; keine Abhängigkeit; teilweise gesichert, neue Messbaseline offen. **Referenz-Warmup-Abnahme präzisiert (2026-09-06):** Der bestehende MTPLX-Runner wartet nun nach `/health.ok` zusätzlich auf `warmup.background.state == done` und verwirft fehlgeschlagene/abgebrochene Schritte, bevor er den separaten Chat-Warmup einreicht. Zuvor zeigte das archivierte Ready-Receipt noch einen laufenden512er Schritt und einen ausstehenden2560er Schritt. Ein sofortiger Foreground-Prompt kann diese laut gepinntem Servercode unterbrechen und später fortsetzen lassen. Keine Veränderung am MTPLX-Server oder dessen Warmup-Defaults; Probe und Fortschritts-/Speicherwatchdog laufen während der gesamten Wartephase. Der neue Abschlussbeleg erfasst die vollständige Health-Antwort. Pending/Done/ Fehlerzustände wurden modellfrei geprüft; neue echte Läufe unter `local-eval-results/20260906-qmm-k-tile/`. Unterschiedliche Warmup-Arbeit zwischen Produkt und Referenz bleibt zu dokumentieren, nicht als identisch ausgeben. - Fortschritt: Erfolgreiche Qwen-Referenzbelege, Runner/Canary sowie aktueller Kern-Quellstand und vorhandenes Release-Binary archiviert. Hashes und Einschränkungen stehen im [Snapshot-Manifest](/Users/gb/Projects/DS4Server/local-eval-results/20260905-before-p13/manifest.md). Der SHA256 des Binary wurde auch aus dem Archiv erneut verifiziert. Quellstand und altes Binary sind ausdrücklich nicht als passender Build ausgegeben. Originaldateien unverändert; lokale Ergebnisarchive sind von Git ausgeschlossen. - Vorhandene gültige JSONL-Receipts, Runner und Eingaben dauerhaft unter einem lokalen Ergebnisverzeichnis sichern; ungültige Läufe eindeutig ausschließen. - Binary-/Kernel-/Source-Diff- und Artefaktidentitäten, Hardware/GPU-Cores, Modellparameter, effektive Flags, MTP-Vertragsdaten, Fan-/Thermalzustand festhalten. Keine erneuten Modell-Downloads oder unnötigen vollständigen Artefakt-Reads während einer Kaltstartmessung. - Abnahme: Ein zweiter Lauf kann aus dem Manifest dieselben effektiven Bedingungen herstellen. Background-Warmup ist beendet oder ausdrücklich Teil der Kaltmessung. Keine Leistungsbehauptung anhand wechselnder ungehashter Arbeitsstände. ### P02 — Identische Texte, Tokens und toolfreier Produktpfad Priorität P0; nach P01; teilweise korrigiert. **Plain-Chat-Konfiguration umgesetzt (2026-09-05):** `Config::plain_chat` gilt im gemeinsamen UI-/Headless-Systempromptbuilder. Sie entfernt Tool-/Skill-/A2UI-Anteile und den eingebauten Coding-Agent-Standardprompt, erhält aber einen benutzerdefinierten Systemprompt unverändert. In der UI unterbindet sie außerdem Workspace-/Datums- Injektionen, Hooks, Tool-Ausführung, automatische Antwortkorrekturen und Ersttitel. Der UI-Default bleibt `false`; die Harness weist ihren Default `--plain-chat on` im Start-Receipt aus. Vergleich nur mit einer frischen UI-Session unter `plain_chat: true`. Bestehende Chats werden nicht bereinigt. `--plain-chat off` ist weiterhin nur ein Prompt-/Inferenzdiagnosepfad, kein Headless-Agent-Executor. Der gemeinsame Prompt-Test über alle Modelloptionen, CLI-Overrides und YAML- Roundtrip bestehen. `tools/qwen-chat-reference.py` verwendet den tatsächlichen MTPLX-Runtime-Tokenizer-Loader und Server-Encoder `_encode_messages_uncached`, nicht einen nachgebauten Jinja-Aufruf. Drei vorbereitete Low-Turns (README-Summary, Story, Python; mit fest vorgegebenen Assistant- und Reasoning-Inhalten) stimmen in gerenderten Bytes und Token-IDs überein: **2489 / 2541 / 2609 Tokens**. Beleg: `local-eval-results/20260905-qmm-loader/plain-chat-reference.json` und `plain-chat-tokens-after.log` (einschließlich History-plus-Checkpoint-Append); der erste Direktversuch ohne den MTPLX-Tokenizer- Wrapper scheiterte und ist kein Referenzbeleg. Es wurde kein Modell generiert. Das ist kein Beweis für alle live erzeugten Historien oder für DS/GLM. P02 bleibt bis zur entsprechenden Frontend-/Referenzabnahme offen; alte Agent-Prompt- Performanceläufe dürfen nicht mit neuen Plain-Chat-Läufen vermischt werden. **Echte erzeugte Historien nachgeprüft (2026-09-05):** Der Fixture-Exporter akzeptiert nun `--source-run`. Für die abgeschlossenen Plain-Chat-AR- und MTP-Rust-Läufe stimmen Rust-Vollrendering und der tatsächliche MTPLX-Server-Encoder in Bytes/Token-IDs sowie re-encodierter History-plus-Continuation überein. AR: 2617/3056/4242; MTP: 2617/3042/4030 Tokens; beide Release-Tests bestanden. Die live fortgesetzten Rust-Checkpoints meldeten dagegen 2617/3054/4238 und 2617/3041/4028. Das ist noch kein Beleg für identische live Tokenfolgen: erhaltene Generationstokens versus erneut gerenderte/encodierte History müssen an der konkreten Grenze verglichen werden; nicht ungeprüft als BPE-Effekt abtun. Beleg: `local-eval-results/20260905-plain-reference/manifest.md`. **Live-Request-Anbindung und reproduzierter Turn-Abschlussfehler (10.09.):** Der kanonische Drei-Turn-Test ruft nun `LiveSession::generate` mit tatsächlichen `ChatTurn`-Nachrichten und `TurnSettings` auf. Eingefrorene Prompt-IDs sind nur noch Assertions, nicht die Eingabe an den Executor. Der Owner hält abgeschlossene und Prefill-Snapshots getrennt; Abbruch vor/nach Streaming, Observer-Fehler und Text-Stopp laufen durch diesen Owner. Ein CPU-Check prüft AR-/MTP-Übernahme von Sampler, Seed und Kontext-/Ausgabelimit bei unveränderter Backend-Policy. Der erste überwachte AR-Lauf scheiterte nach einer exakt referenzgleichen Summary an Turn 2: Produktprompt 3410 statt 3411 Tokens, erste Differenz an Position 3383. Der gespeicherte EOS-Token 248046 war vorhanden, der Template-Zeilenumbruch 198 vor dem nächsten User fehlte. Vorherige History-Append-Tests starteten mit erneut gerenderter History, die diesen Zeilenumbruch bereits enthält. Sie deckten die echte Decode-Grenze nicht ab. Der Fehlbeleg bleibt erhalten unter `local-eval-results/live-session-20260910.9RSmzd/ar.{stdout,stderr}.log`. `engine::render_text_prompt` vervollständigt nun ausschließlich bei einer authentifizierten Qwen-Assistant-History den fehlenden Abschluss: unveränderte vollständige Template-Grenze, Newline nach MTPLX-EOS oder EOS+Newline nach dem skalaren Pre-EOS-Frontier. Generierte Tokens werden nicht neu gerendert und der KV-Prefix bleibt erhalten. DS/GLM sind von dieser Verzweigung nicht betroffen. Der Metadaten-Regressionstest prüft diese drei Frontiers und den Vollrender-Fallback bei ungültigem Tag. Produktiver Controller-/Power-/Checkpoint-Anschluss und die vollständige sechsstellige Performance-Abnahme bleiben offen; dies ist noch keine Freigabe eines UI-Bundles. **Verifikation dieser Anbindung:** Test-/Produktions-Clippy mit `-D warnings`, Release-Testbuild, Format und Diffcheck bestanden. Finale Testbinary-SHA256: `d7705551bebd41c5568fef0f11d593d93fd76accda727f347b075079d3b89e70`. Logs: `/tmp/ds4-live-session-{clippy,production-clippy,build}.log`. Die zwei Request-Checks und der erweiterte Metadaten-/Frontier-Test bestanden unter Supervisor `2048 15 15`. Vollmodell AR/MTP unter `81920 30 45`, sequenziell, SSD-Ngram, unveränderten Referenz-Flags, Chunk 2048, ohne Power-Drosselung, Thinking Low und Seed 0; durchgängiger 100-ms-Canary mit 2-s-Abbruchgrenze. Referenzen bleiben `session-chat-20260910.jT3hf5/reference-{ar,mtp}-boundary.stdout.log`. Es wurden keine Referenztokens oder Assertions abgeschwächt. Beide vollständigen Chats inklusive Owner-Abbruchprüfungen bestanden, ebenso Prompt-/Output-Tokens, Reasoning/Text, Logits-/Hidden-Hashes, Boundary-Snapshots, Cache-Fortsetzungen und MTP-Zyklen. AR Prompt/Cached/Output: 2748/0/635, 3411/3383/1347, 4791/4758/266; MTP: 2748/0/466, 3242/3214/1394, 4669/4636/326. Die tatsächlichen `TurnSettings` (einschließlich f32-Samplerwerte) ändern diese Referenzergebnisse nicht. AR: 583 Canary-Proben, keine Fehler/Stalls, Prefill-max 2,532 ms, Decode-max 1,022 ms, Peak Physical 82.615.580.104 Bytes; Supervisor 62,241 s. MTP: 562 Proben, keine Fehler/Stalls, Prefill-max 4,254 ms, Decode-max 1,145 ms, Peak Physical 83.185.055.752 Bytes; Supervisor 58,907 s. Rohdaten: `local-eval-results/live-session-20260910.9RSmzd/`, `{metadata,request-fixed,ar-fixed,mtp-fixed}.{stdout,stderr}.log`. Das sind Canary-beobachtete Funktionsregressionen, keine neue gepaarte Performance- Abnahme und kein UI-Eventloop-Nachweis. Der Controller ist weiterhin `cfg(test)`. Nichtnull-`min_p` wird vom neuen Request-Adapter ausdrücklich abgelehnt, da der MTPLX-Sampler diesen Filter nicht unterstützt; diese Produktoption ist damit noch nicht integriert. EngineSettings-/Power-/Persistierungsanbindung bleibt offen. - Qwen-Continuation-Fix bereits vorhanden: initialer Systemprompt nur bei Vollrendering, nicht nochmals bei Checkpoint-Append. Regressionstest `engine::tokenizer::tests::qwen_checkpoint_continuation_matches_full_conversation` ist nach vorherigem Fehler bestanden. Noch kein frischer End-to-end-Nachweis. - Test-Konfiguration ohne Skill-/Tool-/A2UI-Anteile über denselben gemeinsamen Produkt-Promptbuilder herstellen, keine nur in der Harness geltende Nachbearbeitung. Effektive UI-Testkonfiguration und Harness-Konfiguration müssen übereinstimmen. - Abnahme: Bytegleicher gerenderter Prompt und gleiche Token-IDs in UI-Headless und Referenz pro Turn, einschließlich Assistant-Reasoning, EOS und Template-Marker; keine Tools/Skills ausgeführt oder angeboten. Low bleibt modellgerecht. - Kleinster vorhandener Check: mit installiertem `DS4SERVER_QWEN38_SOURCE` `cargo test --release engine::tokenizer::tests::qwen_checkpoint_continuation_matches_full_conversation -- --ignored --exact`. ### P03 — Cache-Arbeit und Chat-Fortsetzung aufklären Priorität P0; nach P02; Ursache der AR-Referenz-Cache-Lücke reproduziert, vollständige Cache-/Zeitabnahme weiterhin offen. **Scope-Klarstellung des Nutzers (2026-09-10, maßgeblich für die Integration):** MTPLX ist für Qwens Modellausführung in Prefill/Decode, Kernel und Responsivität die Referenz. Seine SSD-SessionBank samt CAS-Blobs, SQLite-Manifest, Writer-Queue und Eviction muss nicht nachgebaut werden. Für die Persistierung ist auch das bewährte DS4-Verfahren Referenz; die vorhandene Rust-KV-Verwaltung wird wiederverwendet. Der in diesem Arbeitsschritt begonnene separate `session_store.rs` wurde vollständig entfernt, bevor er ausgeführt oder produktiv angebunden wurde. Keine Benutzercaches wurden verändert oder gelöscht. Konkrete Integrationsgrenze im aktuellen Code: - `src/engine/kvstore.rs` verwaltet unabhängig vom Modellzustandslayout die Checkpoint-Dateien, Prefix-Schlüssel, Budget, Zugriffe und Eviction. Keine zweite Datenbank oder zweite Cache-Verwaltung für Qwen einführen. - `src/engine/metal/qwen.rs::save_checkpoint/load_checkpoint` implementiert bereits den dateibasierten Persistierungspfad mit begrenzten IO-Chunks und Veröffentlichung nach `sync_all`/Rename. Das alte FP32-Scratch-Layout ist jedoch kein gültiger Ersatz für die BF16-/Recurrent-/QSA-/MTP-Zustände des neuen Executors. - `qwen_mtplx/session_cache.rs::SessionSnapshot` und der vorhandene Tensorcodec bleiben für die korrekte Zustandsübergabe nutzbar; sie erfordern keine MTPLX- Speicherverwaltung. Ein Restore muss dieselben Folgetokens und Zustandsfrontiers liefern, ohne zusätzliche Voll-Prefills oder Präzisionskonvertierung im Decode. - Priorität hat die produktive Anbindung von `Execution::generate_text` als vollständigem Turn an den gemeinsamen UI-/Harness-Pfad. Eine bytekompatible MTPLX-SSD-Datenbank ist dafür ausdrücklich keine Voraussetzung mehr. **AR-Auswahlfehler belegt (2026-09-05):** Ein erneuter vollständiger MTPLX-Lauf mit `MTPLX_DEBUG_PREFIX_DIVERGENCE=1` reproduziert 5120 gecachte Tokens in allen drei Antworten. Inhalt, Reasoning, Finish-Reason und Usage stimmen vollständig mit dem alten AR-Lauf überein. Alle Antworten enden mit `stop`, Supervisor exit 0, Peak-Footprint 83.78 GB unter der 116.82-GB-Grenze; kein zweiter Inferenzprozess. Die konkrete Kette ist jetzt belegt: 1. `generate_ar` sucht unter `mtp_history_policy="cycle"`; der Server speichert den finalen Generation-Snapshot unter `"committed"`. 2. `SessionBank.restore` wählt zuerst den längsten exakten Prefix (bei Story 7836 Tokens), lehnt dessen Policy ab und versucht keinen kürzeren passenden exakten Eintrag (vorheriger Prefill: 7460 Tokens). 3. Der Near-Prefix-Fallback lehnt **beide** exakten Einträge ab, weil `matched >= entry.prefix_len` gilt (`matched_out_of_range`). 4. Erst der teilweise passende Warmup-Eintrag wird an Recurrent-Grenze 5120 restauriert. Dasselbe tritt beim Python-Turn mit 8643/7896 Tokens auf. Die Debug-Ausgabe bestätigt `clean prefix` und die Präsenz der größeren Kandidaten. Fehlende Session-IDs, fehlgeschlagene Speicherung, Token-Drift oder Eviction dieser Kandidaten erklären diesen Befund nicht. `tools/mtplx-cache-reference.py` reproduziert die Auswahl mit echten MTPLX- Funktionen und leeren Cache-Payloads. Kontrollfall: Nur den inkompatiblen längsten Eintrag entfernen; der unveränderte Exact-Restore nutzt dann den gültigen 7460-Token-Prefix. Kein Modell- oder State-Paritätsbeweis durch diesen Kontrolltest. Belege und Identitäten: [Cache-Diagnosemanifest](/Users/gb/Projects/DS4Server/local-eval-results/20260905-cache-parity/manifest.md). Der Golden Master bleibt unverändert. Diese zusätzliche Referenzarbeit wird nicht zur künstlichen Verlangsamung in Rust nachgebaut. Die alten Agent-Prompt-Läufe sind keine Matched-Work-/2%-Abnahme und dürfen nicht mit der neuen Plain-Chat- Baseline vermischt werden. Rest: Save/Restore/Commit-Zeiten und tatsächlich neue Tokens in der neuen laufenden Chat-Matrix, einschließlich MTP, erfassen. - MTPLX `generate_ar`/`generate_mtpk`, `restore_or_prefill` und Server-SessionBank gegen `Engine`-Checkpoint-Tag, Save/Restore und Pending-Token-Finalisierung verfolgen. Die oben belegte AR-Referenz-Auswahlgrenze in Messungen ausdrücklich ausweisen. - Produktlauf bleibt ein ongoing Chat. Cache-Strategie nicht heimlich verändern, um gleiche Zeiten zu erzeugen. Zusätzlicher Matched-Work-Test mit identischem Prefix/Suffix darf die Engine-Kosten isolieren, ersetzt aber nicht den Produktlauf. - Abnahme: Für alle drei Turns vollständige Tokens/Reasoning/Cache-Frontiers, tatsächlich neu berechnete Tokens sowie Save/Restore-Zeiten; kein unerklärtes Re-Prefill, kein vorzeitiges Ende. Warmup gehört nicht zur Chat-History. ### P04 — Messvertrag für Responsiveness und Zeitanteile vereinheitlichen Priorität P0; nach P01; Lade-/Canary-Phasenzuordnung korrigiert und im Produkt-Runtime-Kontrolllauf geprüft; Gesamt-Messvertrag weiter offen. - Native Canary-Scheduling/Completion, Host-Timer-Verzögerung und echte UI-Eventloop-Verzögerung getrennt ausweisen. Die Engine läuft bereits auf einem eigenen Thread (`src/runtime.rs:108`); ein weiterer Thread beweist keine GPU-Fairness. - Harness-Thread und UI-`Task::perform` benutzen zwar dieselbe native Probe, aber unterschiedliche Scheduling-Umgebungen. Blocking Probe nicht als kooperatives async-Warten interpretieren. Headless misst ohne GUI keinen tatsächlichen Beachball. - Ganze Lebensdauer: Start, Laden, Warmup, Restore, Prefill, erster Token, Decode, Save, Abschluss. Phase bei Probe-Start und -Ende erfassen; p50/p95/p99/max, Samplezahl, In-flight-Alter und Fehler. Fortschritt nur durch echte Modellarbeit. - `run_warmup` startet vor `service.generate` und umfasst damit auch das erstmalige Modellladen. `warmup_result.elapsed_ms` und separat gemeldete Ladezeit dürfen **nicht addiert** werden. Der Loading-Event wird jetzt ausgewertet; der gemeinsame Runtime-Event `Loaded` meldet dieselbe Ladedauer wie die UI-Metriken. Das neue `timing` trennt Ladezeit und restliche Request-Zeit, ohne letztere als reine Rechenzeit auszugeben. Nicht verfügbare Ladedauer bleibt `null`. - Prefill-tok/s = neue Tokens / entsprechende Prefill-Zeit. TTFT und Gesamtzeit separat. Draft, Verify, Acceptance, Commit und Repair dürfen sich im additiven Zeitbudget nicht überlappen (`note_mtp_verification` umfasst momentan auch Repair). - Abnahme: Identischer kleiner Kontrolllauf in UI/Headless mit gleichen nativen Messgrößen; künstlicher Host-Stall und GPU-Stall werden unterscheidbar erkannt. Canary an/aus A/B quantifiziert Messkosten; optional bleibt sie in der UI. **Teilnachweis Phasenzuordnung (2026-09-05):** Release-CLI neu gebaut, zehn `model_eval::tests` bestanden. Ein überwachter Qwen-Plain-Chat-Kontrolllauf bei 100%, Chunk 2048, Low, MTP aus und Canary an endet natürlich mit `pong` (mit führenden Leerzeilen), Supervisor exit 0. Warmup gesamt 12785 ms, davon 8258 ms Modellladen und 4526 ms übrige Request-Zeit (separate Abrundung auf Millisekunden). 140 erfolgreiche Canary-Proben, davon 80 während Loading; eine Probe überschreitet eine Phasengrenze und behält beide Phasen. Zeitstempelreihenfolge, Phasenzahlen, Zeitzerlegung, Ausgabe, Stop und Speichergrenze wurden per Assertions geprüft. Maximale Canary-Completion 3,604 ms; kein erkannter Stall in diesem kurzen Lauf. Startphase bleibt die explizite Zuordnung für Per-Phase-Statistiken; Abschluss- und Beobachtungszeit werden nicht mehr verwechselt. Beleg: `local-eval-results/20260905-phase-attribution/manifest.md`. Frischer Inferenzprozess, **keine** Behauptung eines kalten OS-Dateicaches. Der gemessene `pong`-Turn folgt dem separaten Warmup: keine Reproduktion des kalten UI-Pings, kein GUI-Eventloop-Nachweis und keine Referenz-/2%-Abnahme. Release-Bundle nicht neu gebaut. Restore/Save-Granularität, überlappende MTP-Zeitanteile und die übrigen oben genannten P04-Abnahmekriterien bleiben offen. Der Kontrolllauf belegte auch eine weitere Zeitgrenzen-Lücke: letzter Decode-Progress bei 1294 ms, Request-Ende bei 1603 ms. `timing.decode_ms=670` umfasst diese nachlaufenden 309 ms, während die UI-/Runtime-Rate 49,807 tok/s aus dem letzten Token-Progress stammt (`src/engine.rs`, `generation_started`). `write_result` beendete die Decode-Zeit erst am `Finished`-Event, das nach Checkpoint-Arbeit gesendet wird. Die 309 ms sind **nicht** vollständig als Save-Zeit belegt; EOS/Finalisierung/Checkpoint/Host-Zustellung müssen durch echte Runtime-Grenzen getrennt werden, nicht aus dem letzten Token geschätzt werden. **Decode-Grenze korrigiert (2026-09-05):** Ein lokaler Timer im gemeinsamen `Generator::generate_inner` umfasst den Decode-Loop einschließlich Sampling, Token-/Stop-Verarbeitung und Output-Callbacks. Er endet bei jedem Rückkehrpfad, auch Fehler/Cancel/Stop innerhalb eines spekulativen Zyklus, vor nachgelagerter Pending-Token-Finalisierung und Checkpoint-Arbeit. Keine Kernel-/Sampling-Änderung. `MetricsSnapshot.decode_duration_ns` ist dieselbe Quelle für die neue Stats-Zeile und Harness-`timing.decode_ms`. Die bisherige Host-Zeitspanne bleibt ausdrücklich als `decode_to_request_end_ms` erhalten; historische `decode_ms`-Werte hatten noch diese alte Semantik. `decode_loop_tokens_per_second` verwendet die ganze Loop-Dauer, `decode_tokens_per_second` weiterhin den letzten UI-Progress-Wert. `checkpoint_io` gibt vorhandene gemeinsame Zähler und letzte I/O-Dauern aus; letzte Dauer wird nicht als Summe mehrerer Operationen ausgegeben. Vier Metrics-Tests und zehn Harness-Tests bestanden; der neue Regressionstest prüft Fehler-Rückkehr, Ausschluss nachfolgender I/O und Reset zwischen Requests. Die zeitliche Canary-Zuordnung der nachgelagerten Finalisierung ist dadurch noch nicht korrigiert: ein Loop-Zeitwert ersetzt kein Live-Phasenereignis. **Vollständiger Qwen-Kontrollchat AR/MTP:** Summary des eingefrorenen README, Story, Python nacheinander als ein Chat, jeweils separater Warmup; 100%, Chunk 2048, Low, Canary an. Alle sechs Antworten natürlich abgeschlossen, 1/3/5 History-Nachrichten bestätigt, beide Python-Ausgaben bestehen neun Funktionsfälle. Checkpoint-Schreiben pro Turn 341/377/376 ms (AR), 379/474/464 ms (MTP). Gemeinsame Loop-Rate und letzte UI-Progress-Rate weichen pro Turn um weniger als 0,05% voneinander ab; kein MTPLX-Paritätsnachweis durch diese interne Prüfung. Loop-tok/s: AR 48,916/48,367/48,495; MTP 53,976/38,874/61,596. Die Story bleibt mit MTP langsamer; Draft-Akzeptanz dort 479/1308 gegenüber 79/98 bei Python. Unterschiedliche gesampelte Texte/History und aktive Canary: keine saubere Performance-A/B-Abnahme, aber die Timing-Korrektur beseitigt diesen beobachteten MTP-Rückstand nicht. Canary max AR 102,483 ms / MTP 84,761 ms, keine Fehler; kein GUI-Eventloop-Nachweis. Beide Supervisor exit 0, keine verbleibenden Modellprozesse. Rohdaten, Hashes, Zeitzerlegung und Grenzen: `local-eval-results/20260905-decode-boundary/manifest.md`. Zusatzbefund 2026-09-05: Der vorhandene `DS4SERVER_QWEN38_PREFILL_PROFILE=1` beendet/wartet jeden Layer separat und ist **kein transparenter Profiler**. Vollständiger AR-Chat mit 100% / 2048 / Low und identischen Prompts: Summary-Prefill 21,500 s statt 5,291 s im normalen Lauf; ein anschließender normaler Kontrolllauf wieder 5,257 s. Alle drei Antworten inklusive Reasoning und Tokenzahlen sind in allen drei Läufen exakt gleich. Profiling-Gesamtprozess 91,115 s statt 60,579 s; alle Turns trotzdem regulär beendet. Die Layerzeiten dürfen daher nicht als Kostenverteilung des normalen Produktpfads ausgegeben werden. Einzelne Diagnose- Layer dauern >1 s, obwohl das größte GPU-Command-Buffer-Intervall im Summary nur 263,579 ms beträgt: GPU-Zeit und zusätzliche Host-/Submission-Kosten trennen. Die genaue zusätzliche Kostenursache ist noch offen; keine unbewiesene Zuschreibung an Kernel, Cache-Eviction oder thermische Drosselung. Apples installiertes `xctrace` bietet **Metal System Trace**. Eine gezielte Aufzeichnung mit dem normalen Qwen-Worker als Attach-Ziel (nicht `--all-processes`) wurde gestartet und beim Prozessende automatisch gestoppt. Der Export bestätigt allerdings nur **18,114 s am Laufende**: der große Summary-Prefill fehlt. Im PID-gefilterten Ausschnitt liegen 871 GPU-Compute-Intervalle der Ebene 0 vor, zusammen 12,959 s und maximal 35,604 ms. Das sind Ausführungsintervalle, **keine einzelnen Kernelzeiten**; Shader Timeline ist im Standardtemplate deaktiviert. Somit noch kein Prefill-Ursachenbeweis. Native Traces müssen früher starten. Instruments erfasst trotz Attach auch System-/Prozessmetadaten; Rohtrace und Umgebungsdaten bleiben lokal und werden nicht veröffentlicht. Das Tool benötigt für seinen Instruments-Cache Rechte außerhalb der Workspace-Sandbox; der erfolgreiche Start nach Freigabe ist kein Produktfehler. Diagnosebelege unter `local-eval-results/20260905-gdn-delta/qwen-layer-profile.*` und `qwen-metal-trace.*`. Die anschließende **frühe** Aufzeichnung `qwen-metal-early.trace` erfasst 56,838 s inklusive des großen Summary-Prefills. Produktparameter unverändert, keine Layer- Profiling-Flags. Der vollständige Chat endet mit denselben Antworten und Tokenzahlen wie zuvor. Summary-Prefill 5,289 s, Prozess 63,728 s; Canary-Prefill-Maximum 119,609 ms. `tools/metal-trace-summary.py` wertet die exportierten XML-Daten inkrementell und PID-gefiltert aus; referenzierte Werte, fremde PIDs, verschachtelte Intervalle und überlappende Intervalle sind im integrierten Self-Test geprüft. Der große Summary-Buffer `29116535429` spannt im Trace 3848,372 ms auf, davon **3831,767 ms überschneidungsbereinigte GPU-Ausführung** (234 Intervalle, längstes 85,788 ms). Das deckt sich mit dem nativen Harness-Maximum von 3848,390 ms. Der nachfolgende Prefill-Buffer enthält weitere 1273,938 ms GPU-Ausführung. Somit ist dieser Prefill-Rückstand hauptsächlich GPU-Arbeit, kein gleich langer CPU-Eventloop-Stall. Das identifiziert noch keinen einzelnen langsamen Shader. Gesamtes Trace-Maximum der GPU-Compute-Intervalle: 117,702 ms; kein Shader-Timeline- Profil und keine pauschale UI-Freigabe. Die rohe Instruments-Aufzeichnung belegt ca. 2,7 GiB; die Nachverarbeitung brauchte mehrere Minuten und zwischenzeitlich ca. 16 GiB RSS. Deshalb ausschließlich optionale Einzel-Diagnose, nicht Teil jedes Harness-Laufs. Rohtrace/TOC bleiben wegen enthaltenen System-/Prozessmetadaten lokal. Zusammenfassung: [metal-early-summary.json](/Users/gb/Projects/DS4Server/local-eval-results/20260905-gdn-delta/metal-early-summary.json). ### P05 — Qwen-Submission-Grenzen am aktiven MTPLX-Pfad ausrichten Priorität P0; nach P02, P04; Produktionsintegration und Abnahme weiter offen. Der kanonische Test-Port enthält Encoder-/Taskgrenzen, Streams, Events/Fences und jetzt den gemeinsamen Eval-/Async-Eval-Kontrollfluss einschließlich Abschluss und Fehler-Cleanup, leere materialisierte Daten/Null-Bindings und gemeinsame Array-Ownership anstelle einer externen Materialisierungsliste sowie typisierte Shapes vor der Auswertung sowie geteilte Slice-/Broadcast-/Transpose- Views mit Byte-Offsets bis zur Metal-/Fast-Fence-Bindung sowie Reshape mit geteiltem Backing oder Original-General-Copy sowie AsType-/Dtype-View-Backends mit referenzierten Donation-/Layout-Regeln. Lazy-Array-Konstruktoren und graph-eigene Payloads einschließlich normalisierter Slice-/Contiguous-Knoten führen diese Operationen ohne externe Fixture-Zuordnung aus; RMSNorm und der installierte BF16-Affine-Linear-Pfad sind jetzt mit normalen Input-/Gewicht-Graphkanten angeschlossen. Dessen Layout-/Offset-Pfade verwenden denselben originalen QMV/QMM/Split-K-Dispatcher wie die Modul-Fixtures. Die Unary-Payloads Negative/Square/Exp/Sigmoid/Tanh/Sqrt/Rsqrt übernehmen ebenfalls die originalen Layout-/Donation-/Dispatch-Regeln. Binäre Add/Subtract/Multiply/Divide/Maximum/Minimum/LogAddExp-Payloads samt Broadcasting und gemeinsamer vollständiger Dtype-Promotion sind angeschlossen. Shared-Expert-MLP ist als zusammenhängender Graph mit echter Split- Geschwisteroperation, erfasster compiled SiLU und Down-Projektion verbunden. Vollständige QSA-/Modelloperationen fehlen weiter. Prüfstände stehen in den jeweiligen Abschnitten; frühere Messungen sind dort nicht ersetzt. Weitere Array-Operationen/Promotion, Modellprimitive und vollständige Modellanbindung fehlen noch; P05 ist deshalb nicht abgeschlossen. P06 verändert auch Encoder-Grenzen; Canary-Messungen allein sind kein isolierter Scheduling-Beweis. Details im Abschnitt zum gemeinsamen Eval-/Async-Eval-Ablauf. **Encoder-Zählerdiagnose (2026-09-06):** Optionaler nativer Timestamp-Profiler an bestehenden Encoder-Grenzen, ohne neue CBs/Flushes/Waits. Der vollständige Qwen-MTP- Chat bleibt text-/token-/acceptance-identisch. 588 Vierzeilen-CBs mit 22.932 vollständigen Encoder-Spans decken 99,708% ihrer GPU-Zeit ab. Gemischte Layer-Spans (37/83 Qwen-Dispatches) tragen etwa 88% der instrumentierten Zeit; das isoliert keinen einzelnen Kernel. **Die Zähler verändern die Performance erheblich:** Decode 28,684/14,887/21,614 statt zuvor 57,166/37,921/52,799 tok/s. Daher keine normalen Kernelkosten oder Referenzparität aus diesem Lauf ableiten. Canary-Max 141,889 ms, kein echter GUI-Eventloop-Nachweis. Messkosten und verbleibende Submission-/Kernel-Ursachen bleiben offen. Vollständige Belege und Prüfkommandos: `local-eval-results/20260905-verifier-stage-counters/manifest.md`. - MTPLXs gepinnte Runtime: [device.cpp](https://github.com/ml-explore/mlx/blob/v0.32.2/mlx/backend/metal/device.cpp) `needs_commit`/`commit` und [eval.cpp](https://github.com/ml-explore/mlx/blob/v0.32.2/mlx/backend/metal/eval.cpp) gegen `Commands`, generischen Qwen-Dispatcher, Copy-/Flash-/MTP-Pfade vergleichen. Max-Defaults `ops > 50` / `(data_size >> 20) > 50` sind Batching-Grenzen, keine Millisekundengarantie. `data_size` zählt Elemente, nicht Bytes. - Asynchrone Submissions, Waits, tatsächliche Ressourcen-/Operationszählung, In-flight-Ressourcenlebensdauer und Scratch-Wiederverwendung gemeinsam behandeln. Weder blind pro Layer blockierend warten noch vorhandene Kapazitätsbytes als referenzierte Array-Elemente zählen. Einzelne lange Kernel bleiben P06–P09. - Abnahme: Chunk 2048, Power 100, keine künstlichen Sleeps; identische Ergebnisse, native Completion-Verteilung im wiederholten Referenzbereich ohne Mehrsekunden- Ausreißer. Durchsatz darf nicht zur Bezahlung geringerer Latenz verschlechtert werden. Profiling an/aus darf Submission-Politik für die Vergleichsmessung nicht wechseln. ### P06 — GDN-Prefill und Verifier vollständig abgleichen Priorität P0; nach P02, P04; Conv/Norm-Boundary korrigiert und gemessen, Gesamt-Task offen. Graphstand 2026-09-07: Der gemeinsame GDN-Forward verbindet Fused-Step, Fused-Conv/Verify, Conv1d-Fallback, Output-Fusion und Cache-Fortschreibung mit den unveränderten MTPLX-Kerneln; alle 264 Forward-, 130 Staged- und 24 zusätzlichen Lifecycle-Receipts werden geprüft (siehe „Gemeinsamer GDN-Forward, Output-Fusion und Cache-Fortschreibung“). Äußerer Modellablauf, Maskenerzeugung, Cache-Batchoperationen, Capture-Commit/Repair und Produktintegration bleiben offen. Die historischen Detailbefunde unten beziehen sich auf den bisherigen Produktpfad; der neue Graph ist weiterhin `cfg(test)` und P06 ist nicht abgeschlossen. - MTPLX `models/qwen4_exp.py:388–664` und installiertes `mlx_lm/models/gated_delta.py` gegen `gdn_rows` und die Metal-Kernel `kernel_qwen_gdn_conv_norm_rows` / `kernel_qwen_gdn_delta_rows` vergleichen. - Ausgangsbefund: Rust Conv/Norm lief mit lediglich zehn 1024-Threadgruppen serial über alle Prefill-Zeilen; MTPLX nutzt diese Fusion nur für kleine Breiten, große Prefills nutzen Conv1d/Silu/L2 mit anderen Rundungsgrenzen. Die Delta-Rekurrenz selbst iteriert in **beiden** Implementierungen über Tokens; das allein ist kein Fehler. - Delta: Rust 64 Threads/TG, 32 State-Werte pro Lane versus MLX 128 Threads/TG, vier State-Werte pro Lane. Registerdruck, Occupancy und Reduktionsreihenfolge messen. - Abnahme: gleiche Eingaben/States für S=1,2,3,4,5,6,7,32,2048 einschließlich Chunk-Grenze; Conv-, q/k/v-, Delta- und Output-States gegen aktive Referenz. Einzelkernelzeit und komplette Layerzeit mit identischem Warmzustand vergleichen. Keine allgemeine Toleranzaufweitung, um abweichende Prefill-Rundung zu kaschieren. #### P06-Teilnachweis: Conv/Norm, 2026-09-05 - `tools/qwen-gdn-reference.py` erzeugt ohne Modellladen mit der installierten MTPLX/MLX-Umgebung gleiche BF16-Eingaben, Gewichte und Conv-States. Kleine S verwenden den tatsächlichen MTPLX-Fused-Kernel; große S bilden die aktive Conv1d/SiLU/L2-Operatorfolge ab. Dies ist ein Boundary-Test, kein kompletter Modell- oder Delta-Referenzlauf. - Vorher: S=1..6 exakt; bei S=2048 **2.383.531 q-, 2.381.323 k- und 6.185.718 v-Werte verschieden**, maximale absolute Fehler 0,00024414063 / 0,00390625 / 0,0009765625. Auch S=7 und S=32 schlagen fehl. Conv-States schon vorher exakt. - Korrektur: ab S>6 unabhängige Zeilen parallel dispatchen und die BF16-Grenzen nach Conv, SiLU, L2 und q-Skalierung erhalten. S<=6 bleibt unverändert. Wiederverwendung des vorhandenen GDN-Scratch-Tails für den neuen Conv-State; anschließender bestehender GPU-Copy verhindert In-place-Lese-/Schreibraces. Keine kleinere Chunk-Größe, Leistungsbegrenzung oder künstliche Pause. - Nachher: `qwen_gdn_conv_norm_rows_matches_mtplx` für S=1,2,3,4,5,6,7,32,2048 mit **null Abweichungen** bei q/k/v und Conv-State, einschließlich In-place- State-Übernahme; unveränderte exakte Assertions. Wiederholung nach beiden Chats ebenfalls erfolgreich. Das ist keine Aussage über alle möglichen Eingangswerte. - Isolierte S=2048-Wall-Mediane, zehn Wiederholungen nach einem Warmup: vorher 1,935 ms, nachher zunächst 0,757 ms, MTPLX 1,513 ms. Eine spätere Rust-Wiederholung nach den Modellläufen liegt bei **1,543 ms**. Host-/Graph-Overhead ist enthalten; erhebliche Streuung und nicht kontrollierter thermischer Zustand erlauben daraus **keine** belastbare 2%-Abnahme oder garantierten Beschleunigungsfaktor. - Wichtig für P05: `Buffer::copy_from` → `ds4_gpu_tensor_copy` beendet den aktiven Compute-Encoder und erzeugt einen Blit-Encoder im selben Command Buffer. Damit ändert die notwendige sichere State-Übernahme auch Scheduling-Grenzen. Die Canary-Verbesserung unten darf nicht allein dem schnelleren Conv-Kernel zugerechnet werden. Es wurde kein zusätzlicher Command-Buffer-Flush eingeführt. - Belege: [Messmanifest](/Users/gb/Projects/DS4Server/local-eval-results/20260905-gdn-reference/manifest.md), [numerischer Wiederholungstest](/Users/gb/Projects/DS4Server/local-eval-results/20260905-gdn-reference/rust-gdn-check.log). Offen bleiben vollständige Layer-Outputs, gemeinsame Conv-/Delta-Chunk-States, Verifier-/Commit-State-Abgleich und die isolierte Scheduling-Ursache. #### P06-Teilnachweis: Delta-Rekurrenz, 2026-09-05 Die andere Thread-Aufteilung ist **kein belegter numerischer Fehler**: der neue modellfreie Test `qwen_gdn_delta_rows_matches_mtplx` vergleicht normalisierte, deterministisch zufällige BF16-q/k-Eingaben, BF16-v/beta, FP32-g und einen nichtleeren FP32-Startzustand mit dem tatsächlich verwendeten `mlx_lm.models.gated_delta.gated_delta_kernel`. Der optionale MTPLX-Blocked-Prefill- Patch ist im festgehaltenen Referenzlauf nicht aktiviert und wird nicht als Golden Master untergeschoben. - S=1,2,3,4,5,6,7,32,2048: Ausgaben und FP32-Endzustände bereits **vor einer Kerneländerung exakt identisch**. Die spätere Prüfung umfasst zusätzlich je zwei Teilchunks mit In-place-Zustandsfortsetzung (S=2048 → 1024+1024), ebenfalls exakt. Ganze und geteilte Ausführung werden jeweils gesondert geprüft. - Produktionsdispatch für Prefill/Verify und Capture-Commit lediglich in den gemeinsamen Helper `encode_gdn_delta_rows` extrahiert, damit der Test dieselben Parameter verwendet. Kernel, Geometrie und Mathematik bleiben unverändert. - Isolierter S=2048-Wall-Median: Rust 2,403 ms, Wiederholung 2,366 ms; MLX 3,382 ms. Das ist inklusive Host-Aufrufkosten, mit sichtbaren Startausreißern, und keine ganze Modell-Abnahme. Bei kleinen S liegen Aufrufkosten im Bereich von Zehntelmillisekunden; keine pauschale Aussage, jede Größe sei schneller. - Die gemessene Rekurrenz liefert damit keinen Beleg für den mehrsekündigen Prefill-Rückstand. Kein Umbau auf die Referenzgeometrie allein wegen ihres anderen Layouts. Nächster Kostenabgleich: ganze Layer, insbesondere MoE sowie Submission-Grenzen (P05/P07), statt spekulativer Rekurrenz-Optimierung. - Reproduktion: `tools/qwen-gdn-reference.py --delta`; Rust-Test mit `DS4SERVER_GDN_REFERENCE=` und `--release --ignored --exact`. [Rohbelege](/Users/gb/Projects/DS4Server/local-eval-results/20260905-gdn-delta/delta-reference.json), [abschließender Test](/Users/gb/Projects/DS4Server/local-eval-results/20260905-gdn-delta/rust-final-check.log). Noch kein vollständiger GDN-Layer-, Controls-, Fused-S1- oder MTP-Commit-Beweis. #### Vollständige Qwen-Produktläufe nach der Korrektur Je ein separater Warmup und anschließend Summary → Story → Python in einem Chat; 100%, Chunk 2048, Low, Kontext 131072, T=1, p=0,95, k=20, Seed 12345, Canary an. Systemprompt und drei rohe Prompts stimmen mit dem archivierten AR-Kontrolllauf überein. Die inzwischen korrigierte Tokenisierung reduziert den ersten Prompt von 7490 auf **7460 Tokens** (wie MTPLX). Cache-Unterschiede bleiben offen (P03). | Modus / Turn | Neue / cached Tokens | Output-Tokens | Prefill s / tok/s | Decode tok/s¹ | Nach-Prefill tok/s² | Gesamter Turn s | Draft-Akzeptanz | | --- | --- | --- | --- | --- | --- | --- | --- | | AR Summary | 2294 / 5166 | 464 | 5,291 / 433,6 | 47,46 | 45,62 | 15,604 | — | | AR Story | 59 / 7924 | 861 | 0,812 / 72,7 | 47,04 | 45,93 | 19,557 | — | | AR Python | 72 / 8844 | 91 | 0,858 / 83,9 | 47,50 | 37,89 | 3,260 | — | | MTP Summary | 2294 / 5166 | 488 | 5,487 / 418,1 | 53,59 | 51,25 | 15,162 | 307/495 = 62,0% | | MTP Story | 59 / 7949 | 640 | 0,832 / 70,9 | 40,20 | 38,92 | 17,280 | 350/869 = 40,3% | | MTP Python | 72 / 8649 | 77 | 0,895 / 80,4 | 70,73 | 48,37 | 2,488 | 57/60 = 95,0% | ¹ Letzter Engine-Fortschrittswert; schließt nicht alle EOS-/Checkpoint-/Abschlusskosten ein. ² Completion-Tokens geteilt durch Harness-`decode_ms` bis zum Turn-Abschluss; keine reine Kernel-/Steady-Decode-Zeit. P04 muss diese Grenzen explizit zerlegen. Alle Output-Tokenzahlen umfassen auch Reasoning/Steuertokens. | Vollständiger Lauf | AR | MTP | | --- | --- | --- | | Prozess inkl. Load und Warmup | 60,579 s | 59,592 s | | Laden / Warmup-Lifecycle inkl. Laden (nicht additiv) | 8,914 / 21,333 s | 9,406 / 24,020 s | | Peak Physical Footprint | 84.360.337.288 B | 86.666.337.288 B | | Canary Prefill p95 / max | 110,614 / 117,076 ms | 112,441 / 115,618 ms | | Canary Decode p95 / max | 3,578 / 15,983 ms | 0,513 / 1,114 ms | | Canary Maximum gesamte Laufzeit | 162,362 ms (Warmup) | 145,001 ms (Warmup) | | Canary Samples / Fehler | 574 / 0 | 567 / 0 | | Supervisor-Maximalverzögerung | 45 ms | 48 ms | Beide Prozesse Exit 0; alle drei Turns `finish_reason=stop`. Keine Rückfragen, beide Stories vollständig und kohärent. Summaries decken wesentliche README-Inhalte ab; die MTP-Summary enthält allerdings einen falschen DS4-Link (`github.com/ds4`), also keine pauschale Behauptung fehlerfreier Inhalte. Beide zuvor gelesenen Python- Antworten bestehen elf kleine funktionale Fälle inklusive strikter Schwelle, Duplikaten, leeren Listen und unveränderter Eingabeliste; ohne Tools/Netzwerkrechte. Kein beobachteter >2-s-Canary-Stall in diesen beiden Läufen. Die maximale Prefill- Canary bleibt dennoch weit über der bereits gemessenen MTPLX-Referenz (AR 2,974 ms, MTP 0,550 ms). Mehrsekündige Command Buffer bestehen weiterhin (Summary AR 3,861 s, MTP 3,848 s); deren gesamte GPU-Laufzeit ist nicht gleich Canary-Blockierzeit. Kein Beleg für die Behebung aller UI-Beachballs und keine Sechs-Zellen-/2%-Abnahme. P02 (Skill-Metadaten im Systemprompt), P03/P04 und weitere GDN-/MTP-Pfade bleiben offen. ### P07 — Router, sortierte MoE und Shared Expert Priorität P1; offen wegen vollständiger Modellanbindung und Produktmigration. Die bisherigen verbundenen SparseMoeBlock-Belege betreffen die ältere Buffer-Ausführung mit fusionierten, getrennten und gemischten Expert-/Shared-Modulen sowie aktivierten Decode-/Verify-Flags, nicht den vollständigen kanonischen Arraygraph. Dessen GatherQMM und jetzt auch SwitchGLU, Routing, die zwei fused-MoE-CustomKernel- Knoten sowie der ganze SparseMoeBlock sind an den kanonischen Arraygraph angeschlossen (2026-09-09, siehe folgenden Nachweis). Decoder und äußerer Modellgraph und MTP-Head sind inzwischen verbunden; vollständige Compile-Fusion, Gewichts-/Serving-Anbindung und Produktionsmigration bleiben offen. Keine Produktabnahme. **Decoder-Verbindung 2026-09-09:** `qwen_mtplx/decoder.rs` setzt `qwen4_exp.py:3741` (`DecoderLayer`) mit den bestehenden Arraygraph-Modulen um: optional PLE plus Residual, Attention-Hyper-Connection, GDN beziehungsweise QSA, BF16-Multiply/Reshape/Add, MLP-Hyper-Connection, SparseMoeBlock und erneutes Multiply/Reshape/Add. GDN-, QSA- und PLE-Caches werden an ihre bestehenden Implementierungen durchgereicht. Keine zusätzlichen Eval-/Wait-Grenzen, keine neuen Kernel, keine Änderung von Power oder Prefill-Chunks. Zwei gezielte Tests bestanden unter `test-supervisor 2048 15 15`: - CPU-Graphprüfung: Residual behält BF16, getrennte Multiply-/Add-Knoten, Broadcast-Geometrie und ursprünglichen Hidden-Input; keine Auswertung. - Verbundener GPU-Smoke: beide Attention-Typen jeweils ohne/mit PLE, pro Cache fortlaufend 17 Prefill-, 4 Verify- und 1 Decode-Zeile. Analytisch bekannte, von null verschiedene PLE-/QSA-Residualbeiträge werden bitgenau geprüft; GDN-State-, PLE-Conv-/History-Layouts und QSA-Frontier ebenfalls. Die künstlichen Gewichte verwenden zwei Experten und keinen QSA-Indexer. Dies ersetzt weder die vorhandenen nichttrivialen Komponenten-Referenzbelege noch einen vollständigen Decoder-/Modellvergleich gegen MTPLX. Rohdaten: `local-eval-results/decoder-graph-20260909.pL6JX4/ple.*.log`. Dieser ursprüngliche Decoder-Smoke allein deckt den äußeren Modellaufruf nicht ab. **Äußerer Modellgraph und Capture-Commit, 2026-09-09:** `qwen_mtplx/model.rs` verbindet nun die aufgerufenen Bausteine gemäß `qwen4_exp.py:3778–4134`: dichte/quantisierte Embeddings, optionale übergebene Embedding-Zeilen, SSM-Maske aus Padding/Lengths, erstes PLE-Staging vor der Layerschleife, originales Tile, Decoder-Kette und finaler Mixer. Das letzte Widened-Array bleibt für MTP erreichbar. `emit_logits=false` baut keinen Head; `logits_keep` schneidet vor der Head-Projektion. Tied und untied Head verwenden die vorhandenen Linear-Operationen. Zusammenhängende GDN-Runs schließen PLE/QSA aus. Ein explizit falscher Wert eines der beiden ursprünglichen Compile-Env-Aliase schlägt die AR-Lane-Freigabe. S=1–4, keine SSM-Maske und vorhandener Cache sind die Eintrittsbedingungen; fehlende Conv-/Delta-Zustände lassen den jeweiligen Run eager ausführen. Der vorhandene Replay hält getrennte Traces nach Run, Capture und Shape-/Dtype-Signatur; Zustandspaare und sechs Capture-Zeilen pro GDN werden in Referenzreihenfolge zurückgeschrieben. Bereits ausgewertete Parameter haben nach dem gemeinsamen Evaluator keine Primitive mehr und werden wie in `compile_replace` als Konstanten gehalten, nicht als neue Projektionen gebaut. **Compile-Stand 2026-09-09:** Die drei `compile_simplify`-Durchläufe und die anschließende `compile_fuse`-Absenkung sind jetzt im Modell-Run-Pfad über `trace_compiled` angeschlossen. Acht synthetische GDN-Run-Graphvarianten sind inzwischen gegen tatsächliche MTPLX-Traces geprüft (siehe unten); der vollständige Vergleich mit echten Gewichten und Dispatch-Sequenzen bleibt offen. Der Pfad bleibt `cfg(test)`; weder Serving-Integration noch Performance-Parität sind damit behauptet. **Compile-Simplify 2026-09-09:** `qwen_mtplx/compile_graph.rs` bildet den DFS-/Parents-Graph und die drei CSE-Durchläufe aus dem gepinnten `mlx/compile.cpp:590–800` in Rust ab. Verfügbare Rang-0-Skalare werden über Bits plus Dtype zusammengeführt. Äquivalente Primitive verlangen identische geordnete Inputs und ursprüngliche Primitive-Parameter; identische Primitive- Pointer werden wie in der Referenz ausdrücklich nicht zusammengelegt. Frühere Tape-Position gewinnt, spätere globale Ausgaben bleiben geschützt, Split-Siblings werden in kanonischer Reihenfolge zusammengeführt und die High-Fanout-Gruppierung ab mehr als 100 Parent-Einträgen bleibt erhalten. Neue Deskriptoren werden aufgebaut, ohne den eingefangenen Modellgraph oder seine Gewichte zu mutieren. Der Modell-Run verwendet inzwischen `trace_compiled`; bereits explizit abgesenkte QSA-Graphen verwenden weiterhin `trace`. Slice und SliceUpdate behalten dafür zusätzlich ihre ursprünglichen Stop- Parameter im Primitive. Die GPU-Ausführung benötigt diese nicht, aber die Referenz-CSE vergleicht sie ausdrücklich: beispielsweise Stop=3 und Stop=4 bei Stride=2 sind trotz gleicher Werte keine äquivalenten Slice-Primitive. CustomKernel erbt in der Referenz die standardmäßig falsche Äquivalenz; gleiche Shadertexte allein lösen deshalb keine Zusammenlegung aus. CPU-Graphprüfung bestanden: mehrstufige Zusammenlegung, geschützte Ausgaben, Slice-Parameter, Split-Siblings, identische Primitive-Pointer und 110-facher Fanout. Der angeschlossene Decoder-/Modell-/MTP-Smoke besteht weiterhin beide Tests (`local-eval-results/compile-graph-20260909.WCXIbS/model.*.log`, 0,28 s, gesampelter Peak 313.705.264 Bytes), einzeln unter `test-supervisor 2048 15 15`. Keine Modellgewichte geladen. Diese Prüfungen ersetzen nicht den noch offenen vollständigen Compile-/Dispatch-Tracevergleich gegen MTPLX und sind keine Durchsatzmessung. Zusätzliche Skalarkonstanten-/Identitätsprüfung bestanden (`simplify.*.log`): gleiche NaN-Bitmuster werden zusammengeführt, +0/-0, verschiedene Dtypes und Rang-1-Einzelwerte nicht. CustomKernel-Äquivalenz bleibt falsch; ursprüngliche Deskriptoren bleiben unverändert. Der abschließende verbundene Lauf am finalen Build besteht erneut beide Tests (`final-model.*.log`, 0,27 s, gesampelter Peak 313.492.296 Bytes). Release-Testbuild, warnings-denied Clippy, originale Shader-Quellprüfung sowie Format-/Diffprüfung bestanden. Kein Bundle erstellt. **Compile-Fuse und dynamische Library-Verwaltung, 2026-09-09:** `compile_graph.rs` bildet die Fusionsgrenzen aus `mlx/compile.cpp:805–1028` ab: Tiefe 11, Kandidatenlimit 24, Stream-Gleichheit, Schutz globaler Ausgaben anderer Form, Mehrfachverbraucher und Broadcast-Splitting. Eine zweite DFS ordnet Inputs, Zwischenwerte und mehrere Ausgaben. `fused.rs` erzeugt die originalen Metal-Ausdrücke mit dem unveränderten gemeinsamen Funktor-Header. Die Shadernamen werden umbenannt; die vollständigen 19 SiLU-Kernelkörper stimmen nach ausschließlicher Symbolnormalisierung bytegenau mit dem gepinnten Export überein. Der gemeinsame Compiled-Evaluator unterstützt eingebettete Konstanten, Rang-0-Inputs und mehrere Ausgaben samt Referenz-Donation. Verschachteltes SiLU, SwiGLU und `compute_g` legen bei Tracer-Eingaben ihren Operationsgraph offen, statt bereits abgesenkte Compiled-Primitive einzusetzen (`mlx/compile.cpp:1136`). Damit kann der äußere GDN-Run über diese Grenzen hinweg nach den Referenzregeln fusionieren. Der erste GPU-Test identifizierte eine Lücke der gemeinsamen Metal-Brücke: eine dynamische Library hielt nur ihre zuerst erzeugte Pipeline erreichbar. Beim Wechsel von contiguous zu strided fehlte die weitere Funktion. `ds4_gpu_mtplx_compile` hält jetzt die Library mit allen ihren Funktionen; `ds4_gpu_mtplx_pipeline` erzeugt die jeweils angefragte Pipeline verzögert. Die anfängliche, eventuell ungenutzte Pipeline wird nicht vorab erzeugt. Die Libraries werden mit dem Metal-Kontext freigegeben. Eine weitere fehlgeschlagene Testassertion betraf **die Test-Erwartung**, nicht die Engine: Die Referenz wählt den Compiled-Kernel vor der Ausgabe-Allokation anhand von `data_size` (`metal/compiled.cpp:384,419`). Dieser Wert ist bei frischen Array-Deskriptoren null. Deshalb muss auch bei 65536 logischen Elementen zunächst `_contiguous`, nicht `_contiguous_n`, erwartet werden. Der korrigierte Test prüft ausdrücklich den Nullwert, die gewählte Variante, die vollständige Gridgröße und sämtliche Ausgabewerte; keine Änderung dieser Referenz-Ausführungsreihenfolge. Rohdaten: `local-eval-results/compile-fusion-20260909.K2FLi8/`. Alle GPU-Läufe einzeln unter `test-supervisor 2048 15 15`, ohne Modellladen: - `source.stdout.log`: Konstantenschreibweise und alle 19 SiLU-Quellkörper bestanden; die beiden GPU-Tests bei diesem CPU-Aufruf ausdrücklich ignoriert. - `graph.*.log`: drei Tests für Simplify, Konstantenidentität und Fusion bestanden; Mehrfachausgaben, Broadcast-Splitting, äußere Verbraucher, verschiedene Streams und Tiefengrenze geprüft. - `final-fusion.*.log`: sechs SiLU-Layouts (Rang 1/4/8, positive/negative Strides), drei nichttriviale `compute_g`-Fälle (1/4/17 Zeilen) und vier Mehrfachausgabe-/Skalarfälle (8/65536 Elemente, eingebettet/nicht eingebettet) bestanden. Je Fall eine fusionierte Dispatch; SiLU/GDN bitgleich mit den erfassten Originalkerneln, Mehrfachausgaben exakt zum arithmetischen Soll. - `silu.*.log`: vorhandener Split-/SiLU-Layout-/Donationstest bestanden. - `qsa.*.log`: alle 396 vorhandenen QSA-Compile-Referenzfälle bestanden. - `model.*.log`: beide verbundenen Decoder-/Modell-/MTP-Tests bestanden, einschließlich Cache-Fortsetzung und Capture-Commit; 314.835.760 Bytes gesampelter Peak. Das bleibt ein synthetischer Modelltest. Noch zu prüfen sind vollständige äußere GDN-Run-Traces mit echten Gewichten, die Referenz-Cacheäquivalenz der generierten Shader sowie verschachtelte Compile-Aufrufe mit ausschließlich partiell getraceten Eingaben. Die kurzen Funktionsprüfungen sind keine Messung der UI-Responsiveness oder des Modelldurchsatzes. Serving-/Generator-Verbindung und P16 bleiben offen. Release-Testbuild, `cargo clippy --offline --all-targets --all-features -j 1 -- -D warnings`, originale Shader-Quellprüfung und Format-/Diffprüfung bestanden. Cargo meldet weiterhin die bestehende Future-Incompatibility von `block 0.1.6`. Keine Downloads, kein Bundle und kein Commit in diesem Arbeitsschritt. **Vollständige synthetische GDN-Run-Graphen und Ausgaben, 2026-09-09:** `tools/mtplx-gdn-run-reference.py` ruft die unveränderte ursprüngliche `Qwen4ExpTextModel._get_run_fn((0,), capture)` auf. Reale GDN-/HC-Dimensionen, zwei kleine MoE-Experten, synthetische Nullgewichte und Hidden=0,125; keine Modellgewichte geladen. Acht Kombinationen: S=1/4, Capture aus/an und HC-Fusion aus/an. Referenzmodell ausdrücklich `eval()`, Zustände zwischen HC-Profilen zurückgesetzt und Compile-Cache beim Flagwechsel geleert. Der vorhandene externe Wächter unterstützt dafür zusätzlich `test-supervisor MEMORY_MIB START_SECONDS IDLE_SECONDS --command EXECUTABLE ARGS...`. Er startet den Referenz-Pythonprozess direkt, nicht Cargo oder eine Shell. Direkte Worker-Argumente werden unverändert übergeben; im Rust-Testmodus bleiben die bisherigen Testargumente erhalten. Die zwei CPU-Selbsttests prüfen beide Aufrufarten sowie Speicher-/Start-/Fortsetzungsabbruch und Fehlerbehandlung. Speichertelemetrie gilt weiterhin nur für den direkten Worker, nicht einen beliebigen Prozessbaum. Alle nachstehenden GPU-Läufe einzeln mit 2048 MiB und 15 Sekunden Start-/Fortsetzungsgrenze, ohne Gesamtzeitlimit. Rohdaten: `local-eval-results/gdn-run-20260909.xTGA2h/`. `reference.jsonl` ist **kein gültiger Inferenzbeleg**: beim ersten Export fehlte `model.eval()`, wodurch der Training-Rekurrenzpfad gewählt wurde. `hyper-profiles.jsonl` enthält die acht gültigen Original-Inferenzbelege; `tests/fixtures/mtplx-gdn-runs.jsonl` hält deren Formen, Ausgabe-Hashes und Graphverträge ohne die umfangreichen DOT-Texte. Der Vergleich identifizierte zusammenhängend folgende Abweichungen: - GDN-Q-Skalierung und HC-Inject: Python `scalar * array` läuft durch `array.cpp:631::__rmul__` und erzeugt `multiply(array, scalar)`. Rust hatte Scalar zuerst. Gleiche Arithmetik, aber andere Broadcast-/Fusionsreihenfolge. Beide Aufrufstellen sind korrigiert; andere Scalar-first-Operationen wie C++-`isclose`, Reverse-Power und Reverse-Divide bleiben referenzgerecht. - Nichtfusioniertes HC: die Matmul-Factory erzeugte `Reshape` statt der ursprünglichen Primitive `Flatten` und `Unflatten` (`ops.cpp:3515,3533`). Beide Identitäten samt CSE-Parametern sind jetzt erhalten. Wie im Original benutzen beide denselben Reshape-View-/Copy-Evaluator, keine neuen Kernel. - Der Graphvertrag unterscheidet nun auch `Broadcast` und `AsType` innerhalb von Compiled-Namen. Die Emitterschreibweise bleibt unverändert; eine Normalisierung, die diese Unterschiede verstecken würde, findet nicht statt. Ergebnisse am korrigierten Build: - `final.*.log`: beide verbundenen Decoder-/Modelltests bestanden; alle acht ursprünglichen GDN-Graphvarianten stimmen überein. HC-fusioniert 60–70, unfusioniert 97–107 Primitive, je 3 oder 9 Ausgaben. - `numeric.*.log`: derselbe Test zusätzlich mit **allen** Hidden-/Conv-/Delta- und sechs Capture-Ausgaben pro Capture-Fall. Formen und Float32-SHA256 bytegenau zur Referenz, beide Tests bestanden (0,35 s Testzeit, 315.458.424 Bytes gemessener Peak-Footprint). Der zusätzliche wiederholte Ein-Zeilen-Aufruf prüft auch Fortsetzung nach Capture. - `dense.*.log`: 114 Matmul-Fixtures in jeweils beiden Prepare-Modi bestanden, Peak 203.277.080 Bytes. - `compiled.*.log`: vier Tests bestanden, darunter alle 396 QSA-Compile-Fälle, nichttriviale GDN-/SiLU-Fusion und 19 ursprüngliche SiLU-Quellkörper; Peak 282.493.816 Bytes. Warnings-denied Clippy und originale Shaderprüfung ebenfalls bestanden. Grenze des Graphvertrags: er vergleicht Primitive-Namen, geordnete Abhängigkeiten und Ausgabe-/Siblingpositionen; konstante Blätter gehen nicht mit ihren Bytes ein. Die zusätzlichen Ausgabe-Hashes schließen diese konkrete numerische Fixture, nicht beliebige Gewichte oder alle Shaderparameter ab. Die Nullgewichte ersetzen keine Modellinferenz und diese Zeiten sind keine Durchsatzbelege. Vollständige echte Gewichtsbindung, Generator-/Serving-Anschluss, verbleibende Compile-Cache-/Partial-Tracer-Abweichungen und die sechs P16-Messzellen bleiben offen. Kein Bundle und kein Commit, keine 2%-Paritätsfreigabe. **Gewichtsbindung: Shard-Loader und alle drei Vorab-Fusionen, 2026-09-09:** `qwen_mtplx/weights.rs` lädt wie der ursprüngliche `load_model` die `model*.safetensors` als verzögerte CPU-Load-Deskriptoren über den bereits vorhandenen Safetensors-Loader. Danach bildet derselbe Vorbereitungspfad `_fuse_gate_up_sanitize`, `_fuse_gdn_in_proj_sanitize` und `_fuse_qsa_qkv_sanitize` in ihrer Referenzreihenfolge ab. Kein neuer Loader, keine zusätzliche Runtime-Bibliothek und keine Gewichts-Materialisierung in diesem Schritt. Die Fusionsmetadaten enthalten Bits, Gruppengröße und Split-Positionen für die spätere Konstruktion der ursprünglichen Ersatzmodule. Gate/Up wird bei Experten entlang Achse 1 und beim Shared Expert entlang Achse 0 verbunden; GDN behält die Reihenfolge QKV/Z/B/A. QSA prüft Bias und tatsächliche Packgeometrie, lässt bei abweichender Indexer-Packung nur diesen separat und verzichtet ohne Indexer auf die gesamte QKV-Fusion. Fehlende Parameter oder nicht unterstützte GDN- Bitbreiten behalten den ursprünglichen Pfad. Layer-Indizes außerhalb des Modells werden mit Fehler beendet, nicht durch indizierenden Panic. Originalreferenz: MTPLX `e652d55e2652137a4abcf1312357abbf3eb9d692`, Unterbau `1f8e74e3f12f31365464a6867c6579f0e9b29d85` / Version 0.32.2. `tools/mtplx-weight-fusion-reference.py` ruft die drei unveränderten Sanitize-Funktionen auf. Die Modellattrappen stellen ausschließlich die gelesenen/ersetzten Modulattribute bereit; sie ersetzen keine Fusionslogik. Rohdaten: `local-eval-results/weight-fusion-20260909.pqMBBu/`. - `reference.jsonl` / `rust.*.log`: 18 Varianten bestanden, alle acht Schalterkombinationen plus zehn Bias-/Missing-/Mixed-Pack-/Indexer-Fälle. Rust lädt echte kleine temporäre Safetensors-Dateien, prüft vollständige Namen, Formen, Fusionsmetadaten und sämtliche Float32-Ausgabe-Hashes. Schwache Referenzen auf die ursprünglichen Load-Blätter belegen vor Eval, dass die Fusion die Quellen erreichbar hält, aber noch nicht materialisiert. Testzeit 0,18 s, Peak-Footprint 154.288.872 Bytes. - `installed-reference.json` / `installed-rust.*.log`: Header des **aktuell vorhandenen vollständigen Checkpoints**, 2.466 ursprüngliche Parameter, 1.782 vorbereitete Parameter und 144 Fusionen (96 Gate/Up, 36 GDN, 12 QSA). Namen/Formen/Dtypes als geordneter Metadaten-Hash und sämtliche Rezepte/Splits stimmen mit MTPLX überein. Alle ursprünglichen Blätter und vorbereiteten Ausgaben bleiben ohne Daten; aktiver kanonischer Allocator = 0 Bytes. Kein Eval des Modellpayloads. Rust-Testzeit 0,07 s, Peak-Footprint 10.699.424 Bytes; Referenz-Peak 59.720.256 Bytes. Installierter Pfad: `/Users/gb/Library/Application Support/de.rfc1437.ds4server/models/qwen3.8-flash-next`. Konfigurations-SHA256: `826302af9ff3293cfc9975c9a5a96546fa0aa9f0808505adfc30a62fef806965`; Index-SHA256: `81e77f5b25bb29e25e239ae2f9f324c9cada379ee600441d6c229f1d95a13443`. Vorbereiteter Metadaten-SHA256: `fb7106c8a24a6dc1073cbc386d57c9e60a9f30858ecf294bd9bba215b1bfa8b8`. Dies sind **keine vollständigen Gewichts-Hashes**. Wichtige Artefakt-Präzisierung gegenüber älteren Notizen: In diesen vorhandenen Shards sind Q/K/V 4 Bit, der Indexer ist 8 Bit (je Gruppe 64). Deshalb enthalten alle zwölf QSA-Fusionen **nur drei Projektionen**; Splits `[12288,12800]`. Der ältere Produktpfad prüft diese Packkompatibilität ebenfalls bereits (`qwen.rs::attention_input`); der Befund belegt hier keinen neuen Produktfehler. Eine frühere Aussage über vier gleichartig gepackte Projektionen darf nicht als Eigenschaft dieses aktuellen Artefakts in Messverträge übernommen werden. Alle Prozesse einzeln unter `test-supervisor 2048 15 15`, ohne Modell-Download. Abschließender gemeinsamer Lauf am finalen Build (`final.*.log`): beide Tests bestanden, 0,20 s Testzeit, Peak-Footprint 154.223.336 Bytes. Zusätzlich geprüft: ungültiger Modell-Layerumfang wird vor der ersten Fusion ohne Parameterverlust abgewiesen. Release-Testbuild, warnings-denied Clippy sowie Format-/Diffprüfung bestanden; kein Bundle und kein Commit. Die neuen APIs sind noch Teil des testinternen kanonischen Ports. **Offen:** restliches Sanitize/Norm- und Quantisierungsbinding, echte persistente Decoder-/MTP-Modulkonstruktion aus diesen Parametern, PLE-Sidecar-Anschluss, Generator/Serving und anschließend vollständige Modellmessungen. Die geprüfte Ladevorbereitung ist kein Ersatz für diese Integration und keine Performance-Paritätsabnahme. **Vollständige installierte Modulbindung und Sidecar-Lebenszyklus, 2026-09-09:** `qwen_mtplx/binding.rs` bindet jetzt alle 48 Decoder (36 GDN / 12 QSA), beide Hyper-Connections pro Decoder, MoE, PLE auf Layer 1, Embedding, Ausgabemixer/-kopf sowie optional den eigenen MTP-Decoder aus dem installierten Checkpoint. Bits/Gruppen werden aus der tatsächlichen Modulkonfiguration bzw. der ursprünglichen MTP-Packgeometrie bestimmt. Nur die zwei MTP-Pre-FC-Normen erhalten den ursprünglichen Float32-`+1`-Schritt mit Rückkonvertierung; Trunk-Normen werden nicht erneut verschoben. Fehlende oder ungebundene Checkpoint-Parameter führen zu Fehlern. Raw-HF-Sanitize ist ausdrücklich noch nicht implementiert und wird nicht stillschweigend als konvertiertes Format geladen. `BoundModel` hält die Gewichtsbank und ihre entlehnten Module dauerhaft zusammen, einschließlich veränderlichem Compile-/Staging-Zustand. Dazu wird die bereits transitiv vorhandene, unveränderte `self_cell` 1.3.0 direkt verwendet. Kein lokaler unsicherer Selbstreferenz-Code und keine Kopie der Gewichtspayloads. Der Test prüft unveränderte Moduladresse und erhaltenen Zustand beim Verschieben sowie Rückgewinnung der Gewichtsbank nach Freigabe der Module. `TextModel::post_weight_load` verbindet die bestehenden Tabellenfunktionen wie MTPLX: Sidecar je PLE-Layer, optional Resident-Anschluss, bestehender SSD-Fallback bei gescheitertem Resident-Bind. Die originale Policy verwendet `MTPLX_NGRAM_RESIDENT` bzw. ab 160 GiB physischen RAM den residenten Modus. Die neue Integrationsprüfung pinnt ausdrücklich SSD-Modus; sie lädt keine vollständige Tabelle und behauptet keine neu geprüfte residente Modellinferenz. Referenz: dieselben oben gepinnten MTPLX-/Runtime-Versionen. `tools/mtplx-binding-reference.py` konstruiert **die echten unveränderten MTPLX-Module** über `load_model(lazy=True, strict=True)` und `attach_mtp`. Die Variante `--post-weight-load` ruft zusätzlich die originale Anschlussfunktion und den echten Tabellen-Gather auf. Keine Modellattrappen oder ersetzte Referenzfunktionen. Fixtures: `tests/fixtures/mtplx-binding{,-sidecar}.jsonl`; Rohdaten: `local-eval-results/binding-20260909.ikUh5D/`. - Vier Varianten, alle drei Fusionen gemeinsam aus/an × MTP aus/an: 2.466 / 1.782 / 2.524 / 1.840 Parameter und 626 / 398 / 639 / 411 quantisierte Module. Sämtliche Namen/Formen/Dtypes und Packrezepte exakt; beide MTP-Normausgaben als Float32-SHA256 exakt. - Sidecar in allen vier Varianten auf Layer 1, nicht resident, Prefetch an, ursprüngliche abgerundete Hot-Cache-Kapazität 1023 MiB. Vier echte Lookup-Zeilen `[0,1,255,1]`, Form `[4,160]`, vollständiger Float32-SHA256 exakt. AR-Pipeline-Freigabe bleibt wie im Original ohne residente Tabelle `false`. - Finaler Rust-Test (`final.*.log`) bestanden, 0,12 s Testzeit. Alle übrigen Modellparameter bleiben ausdrücklich ohne materialisierte Daten. Benachbarte Fusionsprüfungen: zwei Tests bestanden, 0,17 s; Tabellen-Routingprüfung bestanden, 0,06 s. Release-Testbuild, gezieltes warnings-denied Clippy für Tests und Format-/Diffprüfung bestanden. - Referenz und Rust ausschließlich einzeln unter externem `test-supervisor 2048 15 15`. Bei diesen sehr kurzen Prozessen sind die 100-ms-Ressourcenstichproben kein lückenloser Peak-Nachweis. Keine neuen Downloads, kein Bundle und kein Commit. **Verbleibender kritischer Integrationspfad:** originale Trunk-Materialisierung einschließlich Parameterbaum-/Eval-Reihenfolge; dauerhafter Engine-/Session-Besitz mit dem neuen BoundModel; Generator/Sampler mit AR- und spekulativen Pfaden; Anschluss an den gemeinsamen UI-/Headless-Runtimepfad. Der kanonische Port ist weiterhin `cfg(test)`; das produktive `QwenExecutor` verwendet weiterhin den alten FP32-Scratch-Pfad. Deshalb wird dieser Abschnitt **nicht** als behobenes UI-Performanceproblem oder Abschluss von P16 gewertet. Die sechs vergleichbaren End-to-End-Messzellen und die 2%-Abnahme aller drei Modelle bleiben offen. **Parameterbaum-/Eval-Reihenfolge, 2026-09-10:** Die echte MTPLX-`Module.parameters()`-Traversal wurde jetzt zusätzlich erfasst (`tools/mtplx-binding-reference.py --parameter-order`). Sie verwendet die Einfügereihenfolge der Module; auch der Python/C++-`tree_visit` vor `mx.eval` sortiert Dictionary-Schlüssel nicht. Die Rust-Bindung zeichnet deshalb die ursprüngliche Modul-Konstruktionsreihenfolge auf, statt die alphabetische `BTreeMap`-Reihenfolge als Auswertereihenfolge zu verwenden: - GDN: Conv, unverknüpfte Eingangsprojektionen, dt_bias, A_log, Norm, Ausgang; der Sanitize-Ersatz `in_proj_fused` wird wie im Original hinten angefügt. - QSA: Q/K/V einschließlich jeweiligem Bias, Ausgang, Q/K-Normen, Indexer; `qkv_fused` ebenfalls nach den verbleibenden ursprünglichen Kindern. - MoE: Router, SwitchGLU, Shared Expert, Shared Gate. Das nicht fusionierte Shared-MLP konstruiert Gate/Down/Up, SwitchGLU dagegen Gate/Up/Down. - MTP: Embedding-Norm, Hidden-Norm, Embedding-FC, Hidden-FC, Decoder, Mixer. `TextModel.parameter_order` hält diese Reihenfolge über die Lebensdauer der Modulbindung. `Bank::materialize` reicht die benannten Wurzeln gemeinsam an den vorhandenen synchronen Graph-Auswerter weiter; keine Einzel-Evals pro Gewicht, zusätzliche Gruppierung oder neue Datei-Ladelogik. Fehlende Namen werden vor dem Eval abgewiesen. Der vorhandene Bindungstest prüft jetzt die vollständigen geordneten Namen gegen die vier originalen SHA256-Belege in `tests/fixtures/mtplx-binding-order.jsonl`. Er übt den Materialisierungspfad an den zwei echten MTP-Normen aus, nicht am gesamten 72.640.204.792-Byte-Trunk. Belege im bestehenden Rohdatenverzeichnis `binding-20260909.ikUh5D`: `reference-order.jsonl` enthält die vollständigen Namen, `order.*.log` den bestandenen Rust-Lauf (vier Varianten, 0,16 s Testzeit). Die zwei verbundenen Decoder-/Cache-Regressionstests bestanden ebenfalls (`order-decoder.*.log`, 0,47 s). Die Prozesse liefen einzeln unter `test-supervisor 2048 15 15`; keine vollständige Gewichts- oder N-Gram-Tabellenmaterialisierung. Release-Testbuild, warnings-denied Clippy für Tests sowie Format-/Diffprüfung bestanden. Kein Bundle, kein Commit. Die zuvor offene Reihenfolge ist damit belegt und der gemeinsame Auswertepfad implementiert. **Noch nicht belegt:** vollständige Trunk-Materialisierung, produktiver Executor-/Generator-Anschluss und die sechs End-to-End-Messzellen. Dieser Befund ist kein Durchsatz- oder UI-Responsiveness-Nachweis. **Vollständiger Trunk und fortlaufender Ping, 2026-09-10:** `qwen_mtplx::execution::Execution` hält jetzt BoundModel, Streams und den modellweiten Cache dauerhaft. Der nicht-lazy Lader materialisiert den gesamten Trunk in der originalen Parameterreihenfolge und schließt den SSD-Sidecar an. `forward` baut denselben Modellgraphen auf; `logits_f32` verwendet den vorhandenen Auswerter. Dieser Ausführungspfad bleibt bis zum Generator-/Produktanschluss `cfg(test)`, nicht der produktive QwenExecutor. Der erste echte Forward deckte eine fehlende Spezialisierung auf: `QuantizedEmbedding` indiziert gepackte U32-Gewichte mit I32-Token-IDs. Der Rust-Gather wies diese Kombination bislang ab. Der Export enthält nun auch U32/I32 und F16/I32 für Front-Gather und den allgemeinen Gather-Wrapper; die gepinnten Kernelkörper sind unverändert. Der bestehende Layouttest prüft beide Kombinationen mit negativen Indizes und zusammenhängenden/strided Quellen. Bestanden unter `test-supervisor 2048 15 15`; Export-Identität ebenfalls bestanden. Keine Cast-Umgehung im Embedding, keine kleinere Testform. Rohdaten: `local-eval-results/execution-20260910.Ngpzu7/`. `tools/mtplx-execution-reference.py` verwendet den tatsächlichen Server-Encoder für Ping/Thinking-low, `load_model(lazy=False, strict=True)`, den originalen Modellaufruf und persistenten Cache. `--decode` folgt für diesen numerischen Oracle greedy bis zum natürlichen EOS; es ersetzt nicht den Serving-Sampler. `--server-defaults` übernimmt die zwölf Einstellungen unmittelbar aus `_server_runtime_env_overrides` (Qwen-Familiendefaults, nicht zusätzlich ein generisches Serverprofil). Die Rust-Paarläufe verwendeten dieselben Werte. | Numerischer Vollmodell-Lauf | Exakt geprüfte Logit-Reihen | Canary max MTPLX / Rust | Ergebnis | | --- | --- | --- | --- | | Direkte Modell-Defaults (`reference-decode` / `canonical-decode`) | 41 Prefill + 56 Decode, je 248.320 Float32-Werte | 4,053 / 4,853 ms | alle SHA256 und Argmax gleich, natürliches EOS; Antwort „Pong! …“ | | Qwen-Server-Familiendefaults (`reference-server` / `canonical-server`) | 41 Prefill + 46 Decode, je 248.320 Float32-Werte | 3,650 / 3,962 ms | alle SHA256 und Argmax gleich, natürliches EOS; Antwort „pong“ | Alle Vollmodellprozesse liefen **nacheinander** unter `test-supervisor 81920 30 45`: 80-GiB-Abbruchbudget, Start-/Fortsetzungsgrenzen statt Gesamtlaufzeitlimit. Zusätzlich durchgehende native UI-GPU-Probe (4-KiB-Blit/100 ms), Testabbruch bei 2-s-Probenstall oder Probe-Fehler. Python verwendet den aus der vorhandenen ObjC-Brücke gelinkten Canary; Rust den vorhandenen model-eval-Monitor. Keine Canary-Fehler oder unvollständigen Proben. Höchster Lifetime-Peak im Familienpaar: Referenz 76.258.077.296 Bytes, Rust 75.878.557.624 Bytes. Keine neue Modellinstallation. Der anfängliche Referenz-Importfehler wurde durch Wiederverwenden der bereits lokalen Python-3.12-Pydantic-Core-Erweiterung derselben Version 2.46.4 behoben; Modell- und Runtime-Revision unverändert. Die instrumentierten Kaltzeiten sind **keine Performance-Abnahme**: etwa 7,734/7,527 s Load, 5,860/5,424 s Prefill und 2,083/2,014 s summierte 46 Decode-Forwards für MTPLX/Rust im Familienpaar. Reihenfolge nicht alterniert, keine sauberen Warmup-Paare, Hash-/Readback-Diagnostik aktiv, kein produktiver Sampler/Generator. Die Tests schließen die zuvor offene reale Trunk-Materialisierung und diese beiden numerischen Cache-Fortsetzungen; nicht UI-Eventloop, spekulativen Generator, laufenden Drei-Prompt-Chat oder P16. Release-Testbuild, gezieltes warnings-denied Clippy sowie Format-/Diffprüfung bestanden; kein Bundle, Commit oder Push. **Sampler-Anschluss: originaler LogSumExp-Pfad, 2026-09-10:** Der tatsächliche serielle Generator ruft `fast_sampling.py` auf, nicht nur die NumPy-Hilfen in `sampling.py`. `_device_serial_support_arrays` normalisiert die Top-p-Masse mittels GPU-Float32-`logsumexp` über das gesamte Vokabular und liest Kandidaten erst an der gemeinsamen Eval-Grenze zurück. Ein vollständiges Host-Readback als Ersatz würde diese Ausführung nicht abbilden. `qwen_mtplx/normalization.rs` ergänzt daher den bislang fehlenden kanonischen Last-axis-LogSumExp-Knoten. Rust übernimmt den unveränderten Auswahl-/Layoutpfad aus `mlx/ops.cpp` und `mlx/backend/metal/logsumexp.cpp` der gepinnten MTPLX-Runtime: Original-`block_logsumexp_*` bis einschließlich 4096 Elemente, darüber Original-`looped_logsumexp_*`, originale Threadgroup-Geometrie, erforderliche Kontiguitätskopie, physische Zeilenreihenfolge, Ausgabe-Strides, kein Input-Donation und keine zusätzliche Synchronisation. Die Kernel kommen aus der bereits gepinnten Metallib, nicht aus einer Ersatzimplementierung. Die Graph-Vereinfachung übernimmt auch `LogSumExp::is_equivalent`. Rohdaten: `local-eval-results/sampler-primitives-20260910.lnnnAf/`. Der vorhandene Original-Fixturegenerator enthält `logsumexp_graph_fixtures`: 150 Fälle aus drei Datentypen (BF16/FP16/FP32), fünf Achsengrößen (1/17/4096/4097/248320), fünf Speicherlayouts und beiden Keepdims-Werten. `tests/fixtures/mtplx-logsumexp-graph.jsonl` enthält die direkt gewonnenen Float32-Ausgabe-SHA256. Fixture-SHA256: `c2e4a855f6f84a355b69e21f1be6fac96a82ac6e0cdeabbddd89260c03c05018`. - Original- und Rust-Läufe jeweils seriell unter `test-supervisor 2048 15 15`, keine Gewichte geladen, keine Downloads. Original-Lifetime-Peak 322.339.608 Bytes; Rust-Lifetime-Peak 213.041.896 Bytes. - `mtplx_logsumexp_graph_matches_reference`: alle 150 Hashes exakt, Ausgabeformen und Nicht-Donation geprüft, leere Eingaben und skalare Eingaben mit Last-axis-Reduktion abgewiesen. Rust-Test 0,73 s; dies ist keine Durchsatzmessung. Der erste Rust-Versuch scheiterte kontrolliert an einem lokalen RefCell-Borrow bei Ausgabe-Allokation; korrigiert, kein GPU-Hang. - `mtplx_compile_simplify_preserves_reference_parent_rules`: bestanden, einschließlich Zusammenlegung äquivalenter LogSumExp-Knoten. Der anfängliche Aufruf mit unqualifiziertem `--exact` führte null Tests aus und zählt nicht; der vollqualifizierte Wiederholungsaufruf führte den Test tatsächlich aus. - Release-Testbuild, gezieltes Clippy mit `-D warnings`, Format- und Diffprüfung bestanden. Kein Bundle, Commit oder Push; kein Testprozess bleibt aktiv. Dies schließt eine benötigte Sampler-Primitive, **nicht P11 oder P16**. Die Kandidaten-GatherAxis-Typkombination und Cutoff-Tie-Selektion sind im folgenden Nachweis ergänzt. Offen bleiben originale Host-Normalisierung und RNG-Ziehungsfolge, Penalties/Fallback sowie der vollständige AR-/MTP-Generator-Anschluss an UI/Harness. Das bereits vorhandene NumPy-kompatible PCG64 wird wiederverwendet. Die vollständigen fortlaufenden Chat-A/B-Läufe aller drei Modelle mit/ohne Spekulation bleiben ausstehend. **Sampler-Anschluss: deterministische Kandidatenauswahl, 2026-09-10:** `qwen_mtplx/sampling.rs::deterministic_top_k` bildet den vollständigen Graphen von MTPLX `fast_sampling._deterministic_mlx_top_k_support` ab: erster ArgPartition, Gather der provisorischen Werte, Min-Cutoff, Greater/Equal, I32-Summe der strikt höheren Werte, I32-Cumsum der Gleichstände, Auswahl kleinerer Vokabular-IDs bis zur Restquote, Where(-inf), zweiter ArgPartition und finaler Gather. Alle Operationen bleiben lazy; kein Host-Readback und keine zusätzliche GPU-Synchronisation innerhalb des Graphen. Die vorhandenen Reduktions-/Scan-Auswerter werden wiederverwendet: Min und I32-Sum nutzen die originalen Reduce-Kernel, Scan übernimmt für vier Byte die originalen N_READS=4-Threadgroup-Regeln, für den bisherigen I64-NGram-Pfad unverändert N_READS=2. GatherAxis ergänzt BF16/F16/F32/U32 mit I32-/U32-Indizes durch Instanziierungen des unveränderten Original-Templates. Die Originalquellprüfung bestätigt weiterhin 17 Custom-Körper und 22 Runtime-Einheiten; kein Kernelkörper wurde für diesen Schritt verändert. Rohdaten: `local-eval-results/sampler-selection-20260910.s0lvxY/`. Der vorhandene Original-Fixturegenerator ruft den tatsächlichen MTPLX-Helper auf und erzeugt `tests/fixtures/mtplx-sampler-selection.jsonl` mit 48 Fällen: Vokabular 17/4097/248320, eine/vier Reihen, Top-k 1/min(20,Vokabular), normales Muster, große Gleichstandsgruppen, vollständig gleiche und nichtendliche Werte. - Zusammenhängender Rust-Selektor: **96 Ausgabe-Hashes exakt**, Token-IDs und Werte für alle 48 Fälle. Zusätzlich tatsächlich dispatchte Min-/I32-Sum-/ I32-Scan-Kernel geprüft. Zehn I32-Scan-Fälle decken alle Threadsize-Bereiche (17/4096/4097/8192/8193) sowie zeilen-/spaltenkontiguierliche Layouts ab. - Bestehende Gather-Regression einschließlich neuer Float-/U32-Kombinationen, 232 ursprüngliche Summenfälle und ursprünglicher NGram-GPU-Test mit 120 Referenzfällen plus I64-Scan-/Donation-/Layout-Zweigen: bestanden. - Original und Rust ausschließlich nacheinander unter `test-supervisor 2048 15 15`, modellfrei, ohne Downloads. Original-Selektor Lifetime-Peak 248.890.040 Bytes; Rust-Selektor 262.374.144 Bytes. Selektortest 1,30 s, kein Durchsatzvergleich. Ein anfänglicher Buildfehler in der temporären Test-Shape-Bindung wurde vor GPU-Ausführung korrigiert. - Release-Testbuild, gezieltes Clippy mit `-D warnings`, Originalquellprüfung, Format- und Diffprüfung bestanden; kein Bundle, Commit oder Push. **Keine Umstellung des heißen seriellen Pfads auf diese teurere Auswahl:** MTPLX verwendet dort zunächst die M=4k-Kandidatenmenge mit nur einem ArgPartition und Host-Sortierung. Der oben portierte Graph wird bei Cutoff-Tie-Spill beziehungsweise vom entsprechenden gebundenen Batch-Pfad benötigt. Die M=4k-Route und Sparse-Normalisierung/RNG sind im folgenden Nachweis verbunden. Die vollständige Generator-Anbindung bleibt ausstehend. P11/P16 und die sechs Modell-/Spekulations-A/B-Abnahmen bleiben offen; diese isolierten Tests belegen keine UI- oder Gesamtperformance-Parität. **Sampler-Anschluss: serielle M=4k-Route und Sparse-Stochastik, 2026-09-10:** `serial_support` bildet `_device_serial_support_arrays` ab: F32-Cast und Temperaturreziprok, ein ArgPartition über M=min(4k,Vokabular), Gather und bei aktivem Top-p LogSumExp/Exp, anschließend **eine gemeinsame Auswertung**. Das Host-Readback kopiert nur die M ausgewählten Spalten je Reihe, auch wenn die Slice einen vollständigen Vokabular-Stride besitzt; kein zusätzlicher GPU-Pack oder Full-Vocab-Readback. Host-Lexsort, Top-p-Präfixmasse und Cutoff-Spill bleiben unverändert. Nur bei mindestens einem Spill folgt eine zweite Auswertung des deterministischen Selektors für alle Reihen; ersetzt werden anschließend ausschließlich die Spill-Reihen. Der Sparse-Verteilungspfad übernimmt `_serial_row_distribution`, die zweite Normalisierung im `SparseDistribution`-Konstruktor, erste Treffer bei Token-Lookups, Vereinigung/Residual und die bedingte Korrekturziehung. Kein neuer RNG: vorhandenes `Rng::new_qwen`/PCG64 wird verwendet. NumPys [paarweise Summierung](https://raw.githubusercontent.com/numpy/numpy/v2.4.4/numpy/_core/src/umath/loops_utils.h.src) und [CDF/Choice-Reihenfolge](https://raw.githubusercontent.com/numpy/numpy/v2.4.4/numpy/random/_generator.pyx) wurden gegen Version 2.4.4 geprüft: kumulative Summe, Division durch den letzten CDF-Wert, Searchsorted rechts. Eine Punktmasse verbraucht weiterhin eine Ziehung; Verify zieht zuerst für Akzeptanz und nur bei Rejection erneut. Die BSD-3-Clause-Mitteilung zum Summierungsport steht im Rust-Quelltext; bei späterer Produktintegration ist sie auch in die ausgelieferten Lizenzhinweise aufzunehmen. Der kanonische Pfad ist weiterhin nur im Testbuild enthalten. Rohdaten: `local-eval-results/sampler-serial-20260910.h4pidl/`. - 108 tatsächliche Original-Helper-Aufrufe: Vokabular 17/4097/248320, eine/vier Reihen, Top-p 0,1/0,95/1,0, Temperatur 0,6, k=20 (am Vokabular begrenzt), eindeutige Werte, Gleichstandsgruppen, uniforme/scharfe, nichtendliche und gemischte Spill-/Nicht-Spill-Reihen. - Token-IDs und alle endlichen Float64-Werte bitgenau; NaNs werden in beiden Receipts kanonisiert, ihre ungültige Verteilungsmasse bleibt erhalten. Die Originalzahl expliziter `mx.eval`-Aufrufe stimmt mit den expliziten kanonischen GPU-Commits überein (automatische Primitive-Commits getrennt). Der tatsächlich dispatchte Tie-Scan stimmt mit der Original-Fallbackzahl überein, nicht nur mit einer vorhergesagten Verzweigung. - 252 daraus erzeugte Sparse-Verteilungen: normalisierte Float64-Werte und 8.064 gewöhnliche Tokenziehungen exakt. Dazu 8.064 Verify-Entscheidungen, davon **7.559 Akzeptanzen und 505 Korrekturen**, einschließlich exakter Akzeptanzmassen und Residual-Verteilungen. Je Sequenz ist der nächste PCG64-Wert ebenfalls exakt; keine versteckten zusätzlichen RNG-Ziehungen. - Alle drei `mtplx_sampler_`-Tests gemeinsam bestanden, 0,44 s Testdauer, Lifetime-Peak 258.835.224 Bytes. Original-Support-Peak 355.943.216 Bytes, ursprüngliche CPU-Verteilungsprüfung 87.933.600 Bytes. Alle Läufe seriell unter `test-supervisor 2048 15 15`, keine Modelle/Downloads. - Release-Testbuild, gezieltes Clippy mit `-D warnings`, Format-/Diffprüfung bestanden; kein Bundle, Commit oder Push. Reine Diagnostikzeiten, keine Aussage zu Modell-Token/s oder UI-Latenz. **Sampler-Anschluss: Dense-Verteilung und Bad-mass-Fallback, 2026-09-10:** `dense_probabilities` übernimmt den Host-Float64-Pfad `softmax` und `apply_top_p_top_k`, einschließlich deterministischer Top-k-Gleichstände, Top-p-Präfixmasse und erneuter Normalisierung auch ohne aktive Filter. Die abschließende paarweise Summierung behält die Nullpositionen des vollen Vokabulars bei. Der plurale GPU-Einstieg `sparse_distributions` übernimmt die serielle Route und liest volle Host-Logits erst bei der ersten ungültigen Reihe; weitere ungültige Reihen verwenden diesen Readback wieder. Der originale Sparse-Fallback liefert bei ungültiger Host-Masse Token 0; der gewöhnliche Dense-Pfad meldet dagegen einen Fehler. Greedy oder deaktiviertes Top-k liefern am pluralen Einstieg unverändert `None`. Rohdaten: `local-eval-results/sampler-fallback-20260910.Csse1Y/`. 150 Originalfälle (30 GPU-Batches mit je vier Reihen und 120 Dense-Fälle) stimmen überein: Sparse-IDs und Float64-Bits vollständig, Dense-Werte über den vollständigen Float64-SHA256 beziehungsweise denselben Fehlerzweig. Vokabular 17/4097/248320, uniforme/scharfe/eindeutige/nichtendliche/gemischte Reihen, Top-p 0,95/1, Top-k 0/20, Temperatur 0/0,6. Alle vier bisherigen Sampling-Tests gemeinsam bestanden (0,68 s); Lifetime-Peak Rust 276.022.040 Bytes, Original 356.614.984 Bytes. Beide seriell unter `test-supervisor 2048 15 15`, ohne Modell oder Download. Release-Testbuild und gezieltes warnings-denied Clippy bestanden. Keine Kernelkörper geändert. Das ist noch kein vollständiger `_sample_from_logits`-Einstieg: Dense-Tokenziehung, Penalties und die eigentliche Generator-Verbindung sind davon getrennt. **Sampler-Anschluss: originaler GPU-Argmax, 2026-09-10:** Der vorhandene Reduktionsbaustein enthält jetzt `ops.cpp::argmax(axis)` und `metal/primitives.cpp::ArgReduce::eval_gpu`. Der Aufruf verwendet unverändert `argmax_bfloat16`/`argmax_float16`/`argmax_float32` aus der gepinnten Metallib, keinen nachgebauten Kernel. Achsen-/Input-/Output-Strides, Scalar-Platzhalter, uint32-Ausgabe und Dispatch entsprechen dem Original (vier Elemente je Thread, Rundung auf 32, Begrenzung durch die tatsächliche Pipeline). Singleton-Achsen liefern den originalen Zeros-Pfad; andere Eingaben werden weder für die Reduktion kopiert noch als Output-Allokation gespendet. Die CSE-Äquivalenz enthält die Reduktionsachse wie im Original. Rohdaten: `local-eval-results/sampler-argmax-20260910.nHvwG6/`. 480 Originalvergleiche mit BF16/F16/F32, Achsenlängen 1/17/4096/4097/248320, keepdims an/aus, nichtendlichen Werten und Gleichständen. Acht Layouts: gewöhnlich, transponiert, strided, Offset, Broadcast, Vektor, Mittelachse und negative Strides. Alle uint32-Outputhashes und Formen exakt; für jede nichttriviale Reduktion genau ein Originaldispatch mit passender Grid-/Threadgroup-Geometrie, ohne zusätzliche Copy oder Sort. Alle fünf damaligen Sampling-Tests gemeinsam bestanden (1,90 s), Rust-Lifetime-Peak 283.820.776 Bytes, Original 322.323.200 Bytes. Serielle modellfreie Läufe unter dem externen 2-GiB-/15-s-Wächter; Release-Testbuild und gezieltes Clippy bestanden, keine Kerneländerung. Der Primitive-Nachweis ersetzt noch nicht den vollständigen Greedy-Einstieg mit Penalties und dessen vorgeschalteter Auswertung im Generator. **Sampler-Anschluss: Dense-/Sparse-Tokenziehung und Verify, 2026-09-10:** `Distribution` bildet die zwei originalen Verteilungsarten ab. Dense-Sampling behält seine zusätzliche Float64-Normalisierung vor NumPy-Choice; Sparse verwendet weiter die Konstruktorverteilung. Beide verwenden dieselbe CDF-Reihenfolge und den bereits vorhandenen PCG64. Ungültige Dense-Masse liefert einen Fehler vor der Ziehung, keine Token-0-Ersatzantwort. Dense-/gemischte Residual-Verteilungen behalten die vollständigen Vokabularpositionen, Sanitization und erneute Normalisierung. Beide Sparse-Verteilungen verwenden weiter ihren vorhandenen Union-/Lookup-Pfad. Bei leerem Sparse-Residual wird der Target wie im Original unverändert weitergereicht; die bisherige zusätzliche `clone()`-Kopie entfällt (`Cow`). Rohdaten: `local-eval-results/sampler-mixed-20260910.y18CqV/`. Der erste Originaldatensatz belegte jede Sparse-Position des Vokabulars und wurde bei 248320 Tokens vom Wächter nach 16,330 s ohne Fortschritt beendet (`reference.*`, 83 vollständige Receipts). Dies erzwingt im originalen Sparse-Residual quadratisch viele lineare Token-Lookups und bildet die Top-k=20-Testkonfiguration nicht ab. Der korrigierte Datensatz (`reference-topk.*`) enthält weiterhin das **volle Dense-Vokabular**, aber maximal 20 über das Vokabular verteilte Sparse-IDs. Weder Runtime noch Wächtergrenzen wurden dafür verändert. Der Fehlversuch bleibt dokumentiert. - 100 Originalfälle: Vokabular 1/17/129/4097/248320, Dense/Dense, Dense/Sparse, Sparse/Dense und Sparse/Sparse; umgekehrte, identische, disjunkte, nichtendliche und Nullmassen. - 2.560 Tokenziehungen exakt; 20 Sample-Fehlerfälle ohne abweichenden RNG-Verbrauch. 3.200 Verify-Ergebnisse exakt: 1.659 Akzeptanzen, 1.227 Korrekturen, 314 Fehler. Akzeptanzbits und jeweils der nächste PCG64-Wert stimmen ebenfalls überein. - Residual-Art, vollständige Float64-Hashes, Sparse-ID-Hashes und Wiederverwendung des Targets exakt; 20 Residual-Fehlerfälle stimmen. - Alle **sechs** Sampling-Tests gemeinsam bestanden (2,36 s Testdauer), Rust-Lifetime-Peak 298.763.008 Bytes. Korrigierte Originalprüfung: 1,197 s inklusive Wächter, Peak 101.057.184 Bytes. Dies sind Korrektheitsprüfungen und keine Modell- oder Performance-Benchmarks. - Unveränderte serielle Überwachung mit 2048 MiB und 15 s Start-/Fortsetzungsgrenzen, keine Modellladung oder Downloads. Release-Testbuild und gezieltes warnings-denied Clippy bestanden. Bestehende Sparse-Prüfungen bestehen nach gemeinsamer CDF-Nutzung weiter. **Sampler-Anschluss: Raw-Logit-Penalties und Overlay, 2026-09-10:** `apply_penalties_host` und `apply_penalties_gpu` übernehmen die beiden Originalfunktionen aus `sampling.py` und `fast_sampling.py`. Presence und Frequency werden auf [-2,2] begrenzt; das nachgeschaltete sparse Overlay wird nicht begrenzt. Counts beziehen sich weiterhin auf Completion-Tokens, nicht auf Prompt-Tokens. Ohne aktive Counts/Overlay bleibt die Originalidentität erhalten, auch wenn die unbenutzten Penalty-Parameter ungleich null sind. Die GPU bildet die Float64-Deltas auf dem Host, rundet diese zu Float32 und führt für Counts und Overlay je einen unabhängigen `Scatter(Sum, axes=[0])` aus. Der allgemeine Scatter castet Updates **vor** der Addition in den ursprünglichen Logit-Datentyp; BF16/FP16-Logits werden nicht zu FP32 befördert. Der CPU-Pfad bleibt Float64 und verwendet die originale Read-all/Write-all- Reihenfolge der indizierten Subtraktion je Stufe. Deaktivierte Penalties sind keine Kopie und kein neuer Dispatch. Der vorhandene Indexing-Baustein und Copy-/Donation-Pfad werden wiederverwendet. Der neue eindimensionale additive Scatter verwendet die unveränderten Originalkörper `scatter_impl`, Atomic-/Sum-Helfer sowie zwölf spezialisierte Original-JIT-Wrapper (BF16/F16/F32, Updates contiguous/strided, 32/64-Bit Offsets). Für rank-one Indizes wählt auch der Originalplan immer nwork=1. Die Host-Exportnamen des namespaced Wrappers sind explizit gesetzt; der erste Lauf ohne diese Alias-Angabe scheiterte vor dem ersten Scatter-Dispatch (`rust.*`). Die Korrektur betrifft nur den Einstieg, keine Berechnung. Rohdaten: `local-eval-results/sampler-penalties-20260910.kW51NO/`. - 360 direkte Originalfälle: Vokabular 17/4097/248320, BF16/F16/F32, gewöhnliche/strided/Offset/reverse/Broadcast-Logits. Acht Profile: deaktiviert, keine Counts, Counts, Overlay, beide, begrenzte Penalties, Null-Overlay und ein einzelner Count-Eintrag. - Alle vollständigen GPU-Float32- und CPU-Float64-Hashes exakt. Identität bei No-op, kein Dispatch bei No-op, Anzahl separater Scatter-Stufen und Erhalt der vom Aufrufer gehaltenen Eingabelogits zusätzlich geprüft. - Korrigierter Einzeltest bestanden (`rust-export.*`, 1,30 s), Rust-Lifetime-Peak 172.671.720 Bytes; Original 232.211.176 Bytes. Alle sieben Sampling-Tests gemeinsam bestanden (`samplers.*`, 2,70 s), Lifetime-Peak 313.541.472 Bytes. Auch der bestehende QSA-ScatterAxis-Test mit den gemeinsam verwendeten Originaldefinitionen besteht weiter. - Sämtliche Läufe seriell unter `test-supervisor 2048 15 15`, keine Modelle geladen/heruntergeladen. Release-Testbuild, gezieltes warnings-denied Clippy und Originalquellprüfung bestanden. Die Quellprüfung ermittelt die Runtime-Einheiten nun aus dem Export statt einer veralteten Konstanten: 26 Runtime-Einheiten, 17 Custom-Körper/41 Custom-Einstiege plus dynamische QSA-Quellen unverändert zur gepinnten Referenz beziehungsweise ihrem Export. **Sampler-Anschluss: gewöhnlicher Generator-Einstieg, 2026-09-10:** `SamplerConfig`, `distribution_from_logits` und `sample_from_logits` verbinden die geprüften Bausteine entsprechend `generation._distribution_from_mlx_logits` und `generation._sample_from_logits`. Greedy verwendet unverändert den Raw-Dtype-Penalty-Pfad, wertet dessen Logits **vor** der Argmax-Erzeugung aus und verbraucht keinen PCG64-Wert. Der einzelne Sparse-Einstieg flacht die Logits ab, wendet GPU-Penalties an, castet danach zu Float32 und verwendet die serielle Unterstützung mit ihrem originalen Bad-mass-Fallback. Dense castet die unbestraften Logits zu Float32, liest logisch zu Float64 und wendet erst dort die Host-Penalties und Distribution/Choice-Normalisierung an. Ein GPU-Penalty-Ergebnis wird nicht als Dense-Fallback wiederverwendet. Beim Verbinden wurde die Einschränkung des bisherigen Full-Logit-Readbacks auf zusammenhängende Zeilen entfernt. Der bereits vorhandene Integer-Reader teilt nun seine evaluierte, span-validierte CPU-Ansicht mit Float32→Float64: auch negative/mehrdimensionale/Broadcast-Strides werden ohne GPU-Pack oder GPU-Flatten gelesen. Der heiße 4k-Support-Readback bleibt unverändert und kopiert weiterhin nur die ausgewählten Kandidaten. Der plurale Bad-mass- Fallback verwendet denselben vollständigen strided Reader einmal für alle ungültigen Reihen. Rohdaten: `local-eval-results/sampler-entry-20260910.WyVtqa/`. - 1.080 tatsächliche Aufrufeinstellungen des originalen MTPLX- `generation._sample_from_logits`: BF16/F16/F32, Vokabular 17/4097/248320, gewöhnliche/Rank-3/strided/reverse/Broadcast-Logits, periodische/uniforme/nichtendliche Eingaben; Greedy, Sparse Top-k, Dense Top-p und Dense ohne Filter, jeweils Penalties/Overlay an/aus. - Pro Konfiguration drei aufeinanderfolgende Ziehungen mit einem PCG64 und fortgeschriebenen Completion-Counts. Alle 3.240 Ergebnisse stimmen: 810 Greedy-, 810 Sparse-, 1.080 Dense-Ergebnisse und 540 erwartete Fehler. Token, Verteilungstyp, vollständige Float64-/Sparse-ID-Hashes, Count- Reihenfolge und nachfolgender RNG-Wert exakt. - Die Referenz-Python-Aufrufe von eval/argmax werden aufgezeichnet. Der Rust-Test prüft tatsächliche GPU-Commitgrenzen: Greedy hat zwei getrennte Auswertungen; ein bereits ausgewerteter Bad-mass-Host-Readback erzeugt keinen zusätzlichen GPU-Commit. Argmax bleibt dem Greedy-Pfad vorbehalten, Dense-Penalties dispatchen keinen GPU-Scatter. - Alle acht Sampling-Tests gemeinsam bestanden, 6,99 s Testdauer, Rust-Lifetime-Peak 320.389.936 Bytes. Originalsequenzen: 4,114 s inklusive Wächter, Peak 286.769.968 Bytes. Unterschiedliche gesamte Testumfänge; diese Zeiten sind ausdrücklich kein Performance-A/B-Vergleich. - Beide bestehenden N-Gram-Stage-Tests bestehen nach Wiederverwendung des Integer-Readers weiter. Alle Läufe seriell unter dem externen `2048 MiB / 15 s Start / 15 s Fortschritt`-Budget, ohne Modelle/Downloads. Release-Testbuild, gezieltes warnings-denied Clippy, Format- und Diffprüfung bestanden. Keine Änderung an Metal-Kernelkörpern. Dieser Einstieg ist weiterhin Teil des kanonischen Testbuilds. Die Python- Owner-Progress-/Watchdog-Anbindung ist zusammen mit dem vollständigen Generator und den UI-/Harness-Metriken zu verbinden; der Methodenvergleich allein weist weder Produktintegration noch UI-Responsivität nach. **Residenter Keyed-GPU-Sampler, 2026-09-10:** `sampling::lazy_sample` bildet `generation._mx_lazy_sample` vollständig als verzögerten Graphen ab. ArgPartition arbeitet auf den unveränderten Modell-Dtypes; erst die k gewählten Logits werden F32. Top-p verwendet den originalen inklusiven Scan, Bool-Sum, Maximum und Select. Die gepinnte `categorical(sv[None], key)`-Route ist inverse CDF, nicht Gumbel-max: Max/Inf-Behandlung, exklusiver Scan, Uniform und SearchSorted-right. `random.rs` übernimmt U32-Key-Erzeugung, Split und F32-Uniform aus dem gepinnten `random.cpp`; `rbits`/`rbitsc`, Scan, SearchSorted und Reduktionen kommen unverändert aus der originalen Metallib. Der Host-PCG64 bleibt davon getrennt. Keine Auswertung, Rücklesung oder Synchronisation im Graphaufbau. Für Bool-Sum verwendet der gemeinsame Reduktionsplan die originale `remap_reduce_types`-Zuordnung Bool -> Int8-Eingabe / Int32-Ausgabe, ohne Cast-Dispatch. Die vorhandenen Gather-Exporte umfassen nun auch F16/F32 mit U32-Indizes, einschließlich F16-GatherFront mit beiden Arbeitsbreiten. Nur Original-Template-Instanziierungen wurden ergänzt, keine Kernelkörper verändert. CSE berücksichtigt RandomBits-Outputshape und Scan-/Suchrichtung. Belege: `local-eval-results/sampler-resident-20260910.7576Ll/`; Fixture `tests/fixtures/mtplx-sampler-resident.jsonl`, SHA256 `497e1175cf18e2d76d2b18f7547bc27c9138b9f3ea82f2b3bead0cf0f72ac7a3`. - 63 Original-RNG-Fälle: drei vollständige U64-Seeds, zusammenhängende, geslicte und rückwärts gerichtete Keys, leere/gerade/ungerade sowie mehrdimensionale Ausgaben (Uniform bis 4097, Split bis 8194 Elemente). Vollständige U32-Bits- und F32-Uniform-Hashes, vier aufeinanderfolgende Split-Keys und der nächste Key stimmen bitgenau überein. - 324 Sequenzen des echten MTPLX-Samplers mit jeweils vier aufeinanderfolgenden GPU-Key-Ziehungen: Vokabular 17/4097/248320, BF16/F16/F32, vier Layouts, normale/gleiche/nichtendliche Logits, drei Temperature/Top-p/Top-k-Profile. Alle 1296 Tokens und Fortsetzungs-Keys stimmen exakt überein. Rust prüft zusätzlich skalare unevaluierte Ergebnisse, keine Dispatches/Commits beim Aufbau sowie acht RandomBits- und vier SearchSorted-Aufrufe pro Sequenz. - `samplers-export.*`: alle neun Samplertests bestanden, 7,86 s Testzeit, Lifetime-Peak 337.036.080 Bytes. Original-Oracle `reference-fixed.*`: 1,289 s einschließlich Wächter, Peak 282.280.704 Bytes. Verschiedene Testumfänge; ausdrücklich keine Performance-A/B-Messung. - Frühere Versuche im selben Verzeichnis sind nicht als Erfolg gewertet: Python exportiert `bits` nicht öffentlich (Oracle nutzt danach den echten `random.split`-Einstieg); Rust fehlten zunächst Bool-Sum-Kernelzuordnung und F16-GatherFront-Instanziierungen. Die Referenzwerte wurden nicht an Rust angepasst. Alle GPU-Läufe seriell unter dem externen 2048-MiB-/15-s-Start-/15-s-Fortschritts-Wächter, ohne Modell/Download. - Release-Testbuild, gezieltes warnings-denied Clippy, Format-, Diff- und Originalquellprüfung bestanden. P11/P16 bleiben offen: der Sampler allein ist weder ein integrierter Generator noch ein UI-/Performance-Nachweis. - Der bestehende gemeinsame Sum-Graph-Test mit 232 Referenzfällen besteht ebenfalls (`sum.*`, 2,41 s, Lifetime-Peak 396.804.960 Bytes). **Gebundene und seriale Batch-Verteilungen, 2026-09-10:** `BatchedDistributions` und `BoundBatchedDistributions` übernehmen die zwei verschiedenen Wege aus MTPLX `fast_sampling.py`. Der normale Batch-Einstieg verwendet die vorhandene Serial-Support-Auswertung und `_from_execution_arrays`: Zeilensumme vor Vokabularsortierung, dann einmalige Matrix-Normalisierung. Eine einzige ungültige Zeile schaltet **alle** Zeilen auf Host-Sampling um; `-1`-Padding und Nullwahrscheinlichkeiten bleiben erhalten. Das ist nicht der bereits vorhandene Sparse-Listenpfad mit einzelnen Zeilen-Fallbacks. Der vorgebundene Weg friert Temperature/Top-p/gekappte Top-k/Vokabular vor dem Decode-Loop ein, bestimmt den Support auf den rohen F32-Logits und wertet Rows/Indices gemeinsam aus. Anschließend laufen Full-Vocab-Softmax und Top-p in Host-F64 wie im Original. Ungültige Masse bleibt hier ein Fehler, ohne automatische One-hot-Ersetzung. Vorhandene Auswahlgraphen, Readback, PCG64, CDF-Ziehung und Sparse-Konvertierung werden wiederverwendet; kein neuer Kernel. Die Batch-Methoden behalten ihre getrennten Regeln: `probability` nimmt den ersten passenden Eintrag, `sample` filtert positive Einträge ohne zusätzliche Normalisierung, `to_distribution` normalisiert über den originalen Sparse-Konstruktor erneut. Der gemeinsame Choice-Validator wird auch vom bisherigen dichten Sampler benutzt. Ungültige Ziehungen verbrauchen keinen RNG. Der erste Vergleich deckte bei Broadcast-Rows eine Ein-Bit-Abweichung auf. `np.asarray(rows).astype(float64)` verwendet `order='K'`: aus Strides `(0,4)` wird eine Fortran-Anordnung `(8,32)`; die Zeilensummen entstehen dann sequenziell statt paarweise. Das separate Originalexperiment `layout.*` belegt die unterschiedlichen Normalisierer. Rust wählt jetzt anhand der evaluierten 2D-Inputstrides die entsprechende Summationsreihenfolge, ohne Referenzwerte oder Toleranzen zu verändern. Referenzimplementierung: [NumPy 2.4.4 Keep-order allocation](https://github.com/numpy/numpy/blob/v2.4.4/numpy/_core/src/multiarray/ctors.c#L1033), [absolute-stride ordering](https://github.com/numpy/numpy/blob/v2.4.4/numpy/_core/src/multiarray/shape.c#L765). Belege: `local-eval-results/sampler-batched-20260910.5QvwOq/`; Fixture `tests/fixtures/mtplx-sampler-batched.jsonl`, SHA256 `60e35333cc2f11ca950fdef1c3c1bcbc56da76331ce33867ad50a8d9f8719b6c`. - 324 Originalfälle je Route plus fünf Konstruktorfälle: Vokabular 17/4097/248320, BF16/F16/F32, zusammenhängende/strided/reverse/broadcast Vier-Zeilen-Batches, normale/gleiche/gemischt ungültige Logits und drei Temperature/Top-p/Top-k-Profile. 108 globale Fallbacks und 111 erwartete Konstruktor-/Auswertungsfehler. Die vollständigen IDs-/F64-Matrix-Hashes, Einzelkonvertierungen, Probability-Lookups einschließlich negativer und ungültiger Zeilenindizes sowie 17.344 Sample-Versuche mit anschließenden RNG-Werten stimmen exakt. Ablehnungen sind Teil des Vergleichs. - Tatsächliche explizite Commit-Grenzen passen zu den Originalauswertungen; der bereits erledigte Readback bei Host-Fallback erzeugt keinen neuen GPU-Commit. Binden und abgelehnte Greedy-/Top-k-Anfragen lösen keine Inferenz aus. `samplers-layout.*`: alle zehn Samplertests bestanden, 11,96 s, Lifetime-Peak 797.639.856 Bytes. Der fehlschlagende frühere `samplers.*`-Lauf bleibt als Diagnosebeleg erhalten. - Original-Oracle: 2,286 s einschließlich Wächter, Peak 393.233.200 Bytes. Die Testumfänge unterscheiden sich; daraus wird keine Performance-Parität abgeleitet. Alle GPU-Läufe seriell unter 2048 MiB / 15 s Start / 15 s Fortschritt, ohne Modelle/Downloads. Release-Testbuild, gezieltes warnings-denied Clippy sowie Format-/Diffprüfung bestanden. **Device-side Target-prefix-Sampler, 2026-09-10:** `sampling::sample_token_ids` bildet jetzt die unveränderte `fast_sampling.sample_token_ids_from_mlx_logits`-Operationsfolge ab: Float32- Division durch Temperatur, deterministischer Support, begrenzte paarweise Rangordnung (Wert absteigend/Token-ID aufsteigend), Full-vocabulary-LSE und Top-p-Maske beziehungsweise Token-ID-Sortierung vor der Ziehung. Der positive Top-p-Pfad lehnt k > 32 nach Begrenzung auf die Vokabulargröße ab; k <= 0 mit aktivem Top-p bleibt nicht unterstützt. Beide Pfade verbrauchen keinen RNG-Schritt. Greedy verwendet den originalen Logit-Datentyp ohne RNG. `random::categorical_last` übernimmt die tatsächlich unterschiedlichen Referenzpfade: ein einzelner Verteilungsvektor ohne Prefix nutzt Gumbel-Max, ein Singleton-Prefix inverse CDF, mehrere Reihen Gumbel-Max. Die Log-Operation verwendet das originale Runtime-Metallib; die vorhandenen Reduce-, Scan-, Gather- und Threefry-Graphen werden wiederverwendet. Keine neuen Metal-Körper, keine CPU-Ziehung und keine vorgezogene GPU-Auswertung beim Graphaufbau. `KeySequence` bildet Seed, Split und fortgesetzten Zustand ab. Dies ist noch **kein** angeschlossener produktiver threadlokaler Default-RNG: Owner- Lebenszyklus, gemeinsame unkeyed Aufrufe, zeitbasierter Initialseed und Wechsel des Default-Streams müssen im Generator integriert werden. Der aktuelle Sequenzhelfer hält den beim Anlegen übergebenen Stream fest; diese Tests belegen den unveränderten Default-GPU-Stream, keine Streamwechsel-Parität. Nachweis: `tools/mtplx-kernel-fixtures.py::prefix_sampler_fixtures` ruft den originalen MTPLX-Einstieg auf. 162 Fälle mit Vokabular 17/4097/248320, BF16/F16/F32, Vektor/Singleton/2x2-Prefix sowie strided/reverse/broadcast, Muster/Gleichständen/NaN und Unendlichkeiten. Je elf aufeinanderfolgende Aufrufe mit Greedy, nicht unterstützter und abgelehnter Konfiguration zwischen Zufallsziehungen; expliziter Reseed innerhalb derselben Folge. Rust prüft Token-IDs, Rückgabeform, Fehlermeldung und den vollständigen RNG-Zustand nach jedem Aufruf exakt. Zusätzlich keine Dispatches oder Commits beim Graphaufbau. - Fixture `tests/fixtures/mtplx-sampler-prefix.jsonl`, SHA-256 `e74e239d30749f66d74d92eb9124f47de460fbf3f01b338b3adc65fef7bdbd07`. - Rohdaten: `local-eval-results/sampler-prefix-20260910.SIdwjQ/`. Original-Oracle regulär beendet, 1,616 s inklusive Wächter, gemessener Lifetime-Peak 447.480.696 Bytes. - Alle elf `mtplx_sampler`-Tests bestanden, 13,34 s Testzeit / 14,042 s inklusive Wächter, gemessener Lifetime-Peak 815.416.520 Bytes. Original und Rust jeweils einzeln unter 2048 MiB / 15 s Start / 15 s Fortschritt, ohne Modellgewichte oder Downloads. Die Umfänge unterscheiden sich; dies sind keine vergleichbaren Gesamtmodell-Geschwindigkeitsmessungen. - Release-Testbuild, gezieltes warnings-denied Clippy, Originalquellprüfung (17 Körper/41 Custom-Einstiege/26 Runtime-Einheiten plus dynamische QSA), Format- und Diffprüfung bestanden. Keine Bundle-/Commit-/Push-Aktion. **AR-Decode-Verbindung, 2026-09-10:** `ar.rs` und `Execution::decode_ar` verbinden den bereits vorhandenen Modell-/Cache-Graphen mit dem normalen Text-Decode-Zweig von `generation.generate_ar`: - Klassischer synchroner und asynchroner AR-Pfad, Host-PCG64, Penalties nur über bereits generierte Tokens, Stop-Token intern behalten und nicht an den Text-Callback ausgeben. Keine zusätzliche CPU-Konvertierung residenter IDs vor dem Modell-Forward. - Pipeline-Admissibilität, eigener `seed & 0x7fffffff`-Key und originale Reihenfolge: erster Token aus Host-Sampler; aktuellen Schritt async auswerten, Folgeschritt bauen/async auswerten, erst dann aktuellen Token materialisieren. Vorangehende Logit-Zeile bis zum nächsten Schritt behalten. - Die Pipeline hat den finalen Token schon konsumiert; die klassische Schleife hat ihn nur ausgegeben. Finale Cache-Erfassung verwendet daher die vorhandene Pipeline-Zeile oder genau einen klassischen Tail-Forward. Der Modell-Owner schaltet den Pipeline-Modus vor dieser Erfassung zurück; auch Result-Fehler des Decode-/Callback-Pfades stellen den Modus zurück. Antwortzeit wird vor dieser Session-Nacharbeit beendet; Capture-Fehler bleiben separat und vernichten die fertige Antwort nicht. Dieser Einstieg beginnt **nach** Prompt-Restore/Prefill und implementiert den normalen Textzweig. Er ist noch kein Ersatz für den vollständigen Request- Owner: Grammar/Constraint, Repetition-/Loop-/Thinking-Guards samt Übergang von Pipeline zu klassischer Steuerung und die Owner-Progress-Hooks fehlen noch. Die Pipeline-Admissibilität darf daher nicht allein zur Auswahl für solche Requests benutzt werden. `qwen_mtplx` bleibt `cfg(test)`; UI und `model-eval` wurden nicht auf einen unvollständigen Generator umgeschaltet. **Orchestrierungsnachweis:** `ar_driver_fixtures` ruft das unveränderte MTPLX-`generate_ar` mit einer kleinen GPU-Transitionstabelle statt Modellgewichten auf. Prefill, Sampling, Pipeline und finale Erfassung sind die originalen Generatoroperationen, keine nachgebaute Python-Decode-Schleife. 480 Fälle, 1384 interne Tokens, 32 tatsächlich aktivierte Pipeline-Fälle und 192 finale Cache-Erfassungen. 96 Fälle stoppen durch EOS; die zusätzlichen Stop-Sets erzwingen insbesondere den ersten und zweiten Pipeline-Token, also sofortiges EOS und EOS mit bereits laufendem Folgeschritt. Rust stimmt für Tokenfolgen, Callback-Ausgaben, Forward-Eingaben/Reihenfolge/Hidden-Anforderung, Pipeline-Admissibilität, Verify-Zähler und finale Logit-Bytes exakt überein. Dies testet den Decode- Ablauf, **nicht** Qwen-Modellrechnung, den gesamten Session-Owner oder Speed. - Fixture `tests/fixtures/mtplx-ar-driver.jsonl`, SHA-256 `9916c29df3d937c36df1f12a477bcd1160683806b6941faa7ff108f8533307a5`. - Rohdaten `local-eval-results/ar-driver-20260910.Ph2gDy/`. `reference.jsonl`/`driver.*` dokumentieren den ersten fehlgeschlagenen Vergleich von JSON-Float64-Dezimalwerten. Finale Float32-Zeilen werden im `reference-bits.jsonl` unverändert als Byte-Hash erfasst; `driver-bits.*` besteht ohne Toleranzänderung. Der erweiterte maßgebliche Satz `reference-eos.jsonl` / `driver-eos.*` umfasst auch die erzwungenen frühen EOS-Fälle: 0,64 s Testzeit, 1,297 s einschließlich Wächter, gemessener Lifetime-Peak 173.589.272 Bytes. Original-Oracle 1,636 s einschließlich Wächter, Peak 231.129.880 Bytes; unterschiedliche Umfänge, keine Performance-A/B-Abnahme. - Alle elf vorhandenen Sampler-Referenztests (`samplers.*`) danach bestanden. Modellfreie GPU-Läufe ausschließlich seriell unter 2048 MiB / 15 s Start / 15 s Fortschritt. Keine neuen Modellartefakte oder Downloads. **Angeschlossener Vollmodell-Decode:** Der vorhandene installierte Ping-Test behält seine 41 Prefill-Zeilen und 46 vollständigen Decode-Logit-Vergleiche. Zusätzlich setzt er den Cache zurück, evaluiert denselben 41-Token-Prompt und ruft `Execution::decode_ar` auf. Greedy mit `max_tokens=usize::MAX`, also kein geschätztes Antwortlimit: alle 46 Antworttokens und das natürliche EOS stimmen mit `execution-20260910.Ngpzu7/reference-server.stdout.log` überein. Der Callback prüft jeden Token gegen diese Referenz und meldet tatsächlichen Fortschritt. Das ist eine Verbindung zum echten Qwen-Trunk, nicht nur ein Tabellenmodell. Maßgeblicher Lauf `installed-phase.*`: 9,05 s Testzeit / 9,758 s einschließlich Wächter, Lifetime-Peak 75.893.991.712 Bytes, 86 Canary-Proben ohne Fehler/Stall. Maximale GPU-Probenlatenz 3,579 ms beim Laden, 0,620 ms im Prefill und 0,505 ms im Decode. Beide Prefills sind ausdrücklich als Prefill markiert; der erste Lauf `installed.*` hatte den zweiten Prefill noch im Decode-Abschnitt und ist deshalb **keine** Grundlage für phasenbezogene Latenzvergleiche. Unverändert 81920 MiB / 30 s Start / 45 s Fortschritt, nativer Canary während des gesamten Workers mit 2-s-Abbruch, installierter Trunk ohne MTP-Head, `MTPLX_NGRAM_RESIDENT=0`, originale AR-Server-Familiendefaults, Power 100 %. Kein paralleler GPU-Prozess, kein Download. Dieser diagnostische Test nutzt weiter den vorhandenen gemeinsamen 41-Token-Numerik-Prefill, **nicht** den noch zu verbindenden originalen Restore-/Body-/Tail-Requestablauf. Greedy aktiviert keine residente Pipeline. Die 9,758 s enthalten Laden, Referenzprüfungen und zwei Decode-Folgen und sind kein vergleichbarer Modell-Durchsatz. Release-Testbuild, gezieltes warnings-denied Clippy, Originalquellprüfung und Format-/Diffprüfung bestanden. Kein Bundle, Commit oder Push. **Kalter Text-Prefill mit echtem AR verbunden, 2026-09-10:** `qwen_mtplx/prefill.rs` führt den originalen `_prefill`-Body-/Tail-Ablauf aus: Cache-Erzeugung nach dem ersten Abbruchcheck, Chunk-Views auf demselben Promptkörper, bedarfsabhängige Logits-/Cache-Auswertung, Fortschritt nach abgeschlossener Auswertung und separates letztes Prompt-Token. Die rohe Cache-Wurzelmenge folgt `_tree_mx_arrays` über Objektattribute, nicht der abweichenden `cache.state`-Ansicht: inklusive QSA-Kapazität, F32-Mirror, GDN-/PLE-Captures und Alias-Deduplizierung. Nicht ausgewertete Head-Logits werden im External-Emit-Cachepfad vor der Cache-Auswertung freigegeben. 505 originale Referenzfälle decken Wurzelreihenfolge und Prefill-Kontrollfluss ab: 0/1/2/9/2050 Tokens, ungeteilter Körper oder Chunks 1/4/2048, Final-Logits-/Cache-only-/External-Emit-Pfade, Hidden-Ausgabe und Abbrüche. Fixture `tests/fixtures/mtplx-prefill-driver.jsonl`, SHA-256 `5b5fb0ba51480507e6849020b3137af8af2bc4394d95e4277701f9441bb5041e`. Der erste Diagnoseadapter beobachtete fälschlich `rt._count`; originaler Prefill schreibt über `generation._runtime_count` direkt in die Zähler. Nach Anschluss an diesen tatsächlichen Schreibpfad stimmen auch die Chunk-/Fortschrittsereignisse; keine Änderung der Original-Inferenz dafür. `unit-counted.*`: bestanden, 0,874 s Supervisor, Peak 161.759.976 Bytes. Rohdaten: `local-eval-results/prefill-driver-20260910.XwGFhY/`. `Execution::prefill_prompt` ist mit derselben gebundenen Modellinstanz und dem tatsächlichen AR-Decode verbunden. Der installierte Trunk wird ohne Downloads, MTP-Head oder residente N-Gram-Tabelle geladen; Power 100 %, Low, Sampler Temperatur 0,6 / Top-p 0,95 / Top-k 20 / Seed 0, originale AR-Server-Familiendefaults, sustained Prefill 2048. Externer Wächter 81920 MiB / 30 s Start / 45 s Fortschritt, native GPU-Canary durchgehend mit 2-s-Abbruch; ausschließlich sequenzielle GPU-Prozesse. - Ping (`reference-ar.*`, `installed-ar.*`): 41 Eingabetokens, ein Body-Chunk; exakte vollständige F32-Prefill-Logits, alle 68 gesampelten Tokens inklusive EOS und die vollständigen finalen Logits nach 67 AR-Schritten stimmen. Der Rust-Lauf hatte hier noch nur einen Prefill, die Referenz bereits zwei; **kein zeitlich symmetrischer Vergleich**. Diese Diagnoseasymmetrie ist anschließend im Rust-Test korrigiert worden, nicht im Inferenzkern. - README-Summary (`reference-summary.*`, `installed-summary.*`): echter Prompt `Give a summary of the following text:` plus README, 2748 Eingabetokens; Body-Spans 2048 + 699 und letztes Token separat. Exakte erste Prefill-Logits, alle **613 Tokens inklusive EOS**, 612 AR-Schritte und volle finale Logits stimmen. Die Antwort ist eine abgeschlossene README-Zusammenfassung. README-SHA-256 `80c01ea096843312de6662d3cd8c94c8e14bdf286b58824752981fc4920fd1f8`; der Oracle speichert außerdem vollständigen Prompt und dessen Hash. Beide Seiten führen jetzt erst den diagnostischen Fingerprint-Prefill und danach einen frischen Prefill mit anschließendem AR bis natürlichem EOS aus. Dies ist **kein vollständiger Chat-Warmup** und kein ongoing Dreiturn-Chat. - Summary: erster Prefill MTPLX 9,159 s / Rust 6,456 s, wiederholter Prefill 2,256 s / 1,755 s. Rust meldet danach 11,636 s Decode; MTPLX meldet 14,741 s Generation **einschließlich** des wiederholten Prefills. Diese unterschiedlich geschnittenen Rohzähler nicht als gleichnamige Decode-Metrik vergleichen. Supervisor-Gesamtzeit 31,391 s / 26,477 s, Peak-Footprint 81.212.995.568 / 80.948.295.160 Bytes. Kein 2%-Pass aus diesen Einzelmessungen mit Canary, Token-Logging, Fingerprints und nicht balancierter Laufreihenfolge. - Summary-Canary: MTPLX 288 / Rust 243 Proben, keine Fehler/Abbrüche; Prefill-Maximum 0,726 / 0,720 ms, Decode-Maximum 0,520 / 0,737 ms. Diese GPU-Proben messen nicht den produktiven UI-Eventloop. Die Behauptung eines vollständig identischen Cache-Inhalts wäre ebenfalls zu weitgehend: geprüft sind hier Folge-Tokens und finale Logits, nicht jeder Cache-Puffer. Gezielte Nachprüfung: AR-Driver-Regression (480 Referenzfälle, 0,62 s) und alle elf bestehenden Sampling-Tests (13,26 s) unter 2048-MiB-/15-s-Wächter bestanden. Release-Testbuild, warnings-denied Clippy für Binary/Tests, Originalquellprüfung (17 Körper, 41 Einstiegspunkte, 26 Runtime-Einheiten plus dynamisches QSA), rustfmt und Diffprüfung bestanden. Kein Bundle, Commit oder Push. Der kanonische Modulpfad bleibt `cfg(test)`; diese vollständigen einzelnen AR-Interaktionen sind noch nicht die produktive UI-/`model-eval`-Ausführung und kein Nachweis der sechs Endmatrix-Zellen. **Streaming-MTP-Historie am Modell verbunden, 2026-09-10:** `prefill::committed` portiert den kalten Textablauf aus `_prefill_committed_mtp_history_streaming`; `Execution::prefill_mtp_history` bindet dafür die bereits vorhandenen Trunk- und MTP-Cache-Graphen ein. Body-Chunks liefern nur dann Hidden States, wenn das History-Fenster sie benötigt; die Hidden-/Token-Paare werden um ein Token versetzt, passend geschnitten und pro Chunk zwingend ausgewertet. Der letzte Prompt-Token bleibt ein separater Trunk-Aufruf. Chunk-Callback-Fehler werden wie im Original ignoriert, Abbrüche an den separaten Kontrollpunkten dagegen weitergegeben. Target- und History-Zeit sind getrennt. Der explizite History-Positionswert wird berechnet; Qwens originale `mtp_update_cache` ignoriert ihn zugunsten des QSA-Cache-Offsets, und der Rust-Modelladapter tut dasselbe. Rohdaten: `local-eval-results/mtp-prefill-20260910.7S6cT2/`. 656 unveränderte Originalsteuerungsfälle mit kleinen Modell-Testtensoren prüfen Ergebnisse, Forward-/History-Eingaben, Hidden-Slices, Positionen, Zähler-/Heartbeat-/Abbruchreihenfolge und Chunk-Callbacks. Eingaben 0/1/9/2050 Tokens; ungeteilter Körper bzw. 4/2048-Chunks; vollständige/0/1/3/2049-Historie, Cache-/absolute Position, Full-Logits-/Cache-only-/External-Emit-Zweige. Null-Länge des angeforderten History-Fensters wird wie im Original auf 1 geklemmt. Abbruchfälle vergleichen auch die schon ausgeführten Calls. Fixture `tests/fixtures/mtplx-mtp-prefill-driver.jsonl`, SHA-256 `ae00ab6c91b98382c35784309ee35f5d2e641e9f2333e050905d03a4fdae70cf`. Erzeugung mit dem endgültigen Adapter nochmals byteidentisch bestätigt; Rust-Test bestanden (0,26 s, Supervisor 0,968 s, Peak 157.303.552 Bytes). Der erste Fixture-Adapterversuch brach wegen eines fehlenden Runtime-Vertrags vorzeitig ab; korrigiert wurde der Adapter, nicht MTPLX oder dessen Algorithmus. Vollmodell-Nachweis (`reference-installed.*`, `installed.*`): installierter Trunk plus tatsächlicher MTP-Head, README-Summary mit 2748 Eingabetokens, Power 100 %, sustained Prefill 2048, originale MTP-Server-Familienflags und SSD-N-Gram-Policy. Keine Downloads, keine parallelen GPU-Läufe. Externer 81920-MiB-/30-s-Start-/45-s-Fortschrittswächter und durchgehende native GPU-Canary mit 2-s-Abbruch unverändert. - Vollständige Historie: 2747 verschobene Token-/Hidden-Paare in zwei Chunks; Cache-Offset 2747 vor bzw. 2748 nach erstem Draft. Vollständige F32-Hashes für letzte Trunk-Logits, letzte Trunk-Hidden, erste Draft-Logits und Draft-Hidden sind exakt identisch zu MTPLX. - Letzte drei History-Tokens: erster Body-Chunk ohne Hidden-Ausgabe, aus dem zweiten nur die letzten drei Paare für den Head; History-Positionsbasis 2744, Cache-Offset 3 vor bzw. 4 nach Draft. Dieselben vier Tensorprüfungen sind exakt; die Draft-Tensoren unterscheiden sich erwartungsgemäß vom Vollhistorie-Fall. Die Fixture prüft auch absolute Positionsmetadaten; der Vollmodell-Lauf nutzt Qwens normalen Cache-Positionsmodus. - Rohzeiten MTPLX/Rust: vollständiger Target-Prefill 11,202/5,509 s, History 0,270/0,291 s; Drei-Token-History-Fall Target 2,221/1,710 s, History 0,0133/0,0154 s. Die höheren Rust-History-Einzelwerte sind damit ausdrücklich festgehalten. Keine Wiederholungs-/Reihenfolgebalance, kein sauberer Speed-Test und kein belegter 2%-Pass oder harter Rücknahmegrund. - Supervisor insgesamt 20,833/13,477 s; Peak-Footprint 81.452.808.584/81.093.507.008 Bytes. Canary 189/126 Proben, kein Abbruch, Prefill-Maximum 1,391/0,918 ms. Die kurzen ersten Drafts trafen kein 100-ms-Probenfenster: **keine gemessene Decode-Latenz** aus diesem Test. Alter AR-Prefill (505 Fälle) weiterhin bestanden. Release-Testbuild, warnings-denied Clippy für Binary/Tests, Originalquellprüfung, rustfmt und Diffprüfung bestanden. Keine neue Metal-Implementierung, kein künstliches Cache-Leeren, keine Power-/Chunk-Absenkung, kein Bundle/Commit/Push. Dies ist noch kein vollständiger `generate_mtpk`-Lauf bis EOS und keine produktive UI-/Harness-Integration; der kanonische Pfad bleibt `cfg(test)`. **Standard-MTP-Generator bis EOS mit Context-copy verbunden, 2026-09-10:** `Execution::decode_mtp` verbindet den echten MTP-Head, die vorhandenen Sampler/PCG64-Verteilungen, batched Verify, Family-Capture-Commit, Snapshot-Rollback/Reforward, persistente autoritative MTP-Historie, Bonus/Pending-Correction und finalen Pending-Commit. Der Original-Oracle ruft `generate_mtpk` auf; keine nachgebaute Referenzschleife. Natürlicher EOS, Sampler 0,6 / 0,95 / 20, Seed 0, Draft-Tiefe 3, History `committed`, Qwen-Low, Power 100 %, Prefill 2048, serverseitige Familienflags und SSD-N-Gram-Policy sind innerhalb jedes Paares identisch. Rohdaten: `local-eval-results/mtp-generator-20260910.pYRdXK/`. Der erste vollständige Ping (`rust-ping.*`, nochmals `rust-ping-trace.*`) scheiterte am 30. ausgegebenen Token: MTPLX 328, Rust 264. Die ersten neun Draft-/Acceptance-Zyklen stimmten, im zehnten nahm Rust alle drei Drafts an, während MTPLX den zweiten ablehnte. Ursache im neu verbundenen Generator: der Family-Commit bekam weiterhin `capture=true`, obwohl MTPLX seinen `verify_capture_scope` VOR dem Commit beendet. Beim Ein-Token-Replay der PLE-Schicht verhinderte das den originalen Fused-GDN-Step und änderte den Folgezustand. Korrektur: Commit mit `GraphOptions::from_env(false, false)`, wie im bereits geprüften Modelloperationsadapter. Keine Kerneländerung, keine Toleranzlockerung und kein geänderter Seed/Prompt. - Ping nach Korrektur (`rust-ping-capture-fix.*`): alle **52 Tokens inklusive EOS**, **19 vollständige Zyklen**, 57 Drafts/33 angenommene Drafts, finale Logits und Hidden States als vollständige F32-SHA-256 sowie MTP-Offset 92 exakt wie MTPLX. Kein vollständiger Trunk-Cache-Hash behauptet. - Die ursprüngliche Summary enthielt fünf Runden mit leerer MTP-Draftliste. Das ist KEINE adaptive Verkürzung der MTP-Tiefe: MTPLX aktiviert auch in der batched Qwen-Lane standardmäßig Context-copy. Dieser Zweig wurde portiert und NICHT für den Vergleich deaktiviert: Prompt-only N-Gram-Index, rückwärtige Match-Verlängerung/neuester Tie-Break, Blockleiter, Probation, EMA/Backoff, Punktmassen-p/q-Akzeptanz, Family-Commit und dessen Original- Rückfall (gesamten Block zurückrollen, nur Primary nachfahren, Copy für den Request deaktivieren). MTP-History enthält die akzeptierten autoritativen Paare, nicht die noch ungeprüfte Korrektur. Auch die optionale RAMP-Fixed- und Fuzzy-Match-Auswahl ist im Index vorhanden; Vollmodell-Abnahme hier ausschließlich mit den unveränderten Standardwerten, RAMP aus. - Summary (`reference-summary-copy.*`, `rust-summary-copy.*`): **2748 Prompt-Tokens, 401 Tokens bis EOS, 135 Verify-Zyklen**, 390 MTP-Drafts/247 angenommene MTP-Drafts. Alle fünf Copy-Ereignisse sind exakt: Block/Accept 8/0, 8/8, 16/4, 8/7, 24/0; auch Extension, Korrektur, Position und übrige Zyklen stimmen. Vollständige finale Logits/Hidden-F32-Hashes identisch, MTP-History-Offset 3148, finaler Zustand commit-fähig. Die Ausgabe ist dieselbe abgeschlossene README-Zusammenfassung wie im Original. - Summary-Rohzeiten: Rust Prefill 6,540 s, Decode 5,619 s, davon gemeldete Draft-Aufrufe 0,679 s, Verify 4,614 s, History 0,143 s; separate Reforward- Repair-Zeit 0. MTPLX meldet 10,330 s Generation inklusive 4,582 s Prefill. Diese Zähler haben noch keine vollständig vereinheitlichten Messgrenzen; aus Subtraktion allein keinen 2%-Pass ableiten. Supervisor-Gesamtzeiten MTPLX/Rust 17,671/18,022 s, Peak-Footprint 82.048.399.848/81.575.557.248 Bytes. Unterschiedliche kalte Prefill-Zeiten, Token-Logging, Canary, Endtensor-Readbacks und fehlende balancierte Wiederholungen schließen eine saubere Performance-Abnahme aus. - Durchgehende Summary-GPU-Canary: MTPLX/Rust 159/170 Proben, keine unvollständige Probe/Fehler/Abbrüche, Prefill-Maximum 0,813/0,746 ms, Decode-Maximum 0,516/0,203 ms. Das ist keine Messung des UI-Eventloops. Alle Vollmodellprozesse liefen einzeln unter 81920-MiB-/30-s-Start-/45-s- Fortschrittswächter und 2-s-Canary-Abbruch. Keine neue Last ohne Wächter. Gezielte Prüfungen: Context-copy-Match/Probation/Backoff/Promptende-Test, bestehende AR-Driver-Regression (480 Fälle), Release-Testbuild, warnings-denied Clippy für Binary/Tests, rustfmt und Diffprüfung bestanden. Kein Bundle, Commit oder Push. Der kanonische Modulpfad bleibt `cfg(test)`; die erfolgreiche Standard-MTP-Interaktion ist noch NICHT die produktive UI-/Harness-Ausführung. Capture-off-Rückfall, Greedy-Copy und optionale RAMP-Konfigurationen benötigen zusätzliche Referenzfälle; sie werden durch die zwei Sampled-Läufe nicht als vollständig abgenommen ausgewiesen. **Warmer Text-Suffix auf dem tatsächlichen MTP-Endzustand, 2026-09-10:** Die Integrationsprüfung der produktiven `Generator::generate_inner`-/ `prefill_suffix`-/Checkpoint-Verträge zeigte eine noch fehlende Voraussetzung: der neue Modellpfad konnte bisher nur kalt vorfüllen. Ein direktes Umschalten der UI hätte deshalb laufende Chats nicht mit MTPLX-Semantik fortgesetzt. `Execution::prefill_restored_suffix` ergänzt den Live-/Restored-Cache-Pfad aus `generation._prefill_restored_prompt_suffix`, ohne Reset oder Nachfahren des bisherigen Kontexts. Es nutzt bestehende Modell-, History-, Slice- und Auswerterfunktionen; keine neue Kernel-Implementierung und kein zweites Modell. - Kurze Suffixe bis zum übergebenen Original-Limit (Default 512) werden in einem Forward mit final-only Logits verarbeitet. Lange Suffixe verwenden einen gemeinsamen Body-Eingabetensor mit Chunk-Views und separatem Tail. - Vor dem ersten neuen Token wird der letzte gespeicherte Hidden-Zustand dem ersten Suffix-Token zugeordnet. Danach werden die um eins versetzten Hidden-/Token-Paare pro Body bzw. Fused-Forward in die bestehende MTP-Historie übernommen und zwingend ausgewertet. Kein MTP-Cache wird neu erzeugt. - Rückgabe und Fortschrittsereignisse halten Target-/History-Zeit auseinander. Der separate Tail meldet Fortschritt, zählt aber wie in MTPLX nicht zu `prefill_chunks`; ein Fused-Forward zählt als ein Chunk. Chunk-Callbackfehler werden ignoriert, Abbrüche an den separaten Kontrollpunkten weitergegeben. Rohdaten: `local-eval-results/restored-suffix-20260910.OovSi9/`. Oracle: `--mtp-generate --restored-suffixes README.md`, echte originale `generate_mtpk` bis EOS und danach der originale warme Suffix-Helper. Der erste Referenzlauf sichert die Tensoren; `reference-counters.*` ergänzt die echten Runtime-Zähler. Rust prüft zuerst erneut sämtliche 52 Ping-Tokens, 19 MTP-Zyklen und Endtensoren und danach die drei Suffixe auf demselben Cache: | Warme Erweiterung | Tokens / bereits im Cache | Fortschritts-Chunks | Runtime-Chunks | Target MTPLX / Rust | History MTPLX / Rust | | --- | --- | --- | --- | --- | --- | | Story-Anweisung | 28 / 93 | 28 | 1 | 0,10313 / 0,10226 s | 0,00359 / 0,00343 s | | README-Summary-Anweisung | 2720 / 121 | 2048 + 671 + 1 | 2 | 2,61440 / 2,58890 s | 0,04834 / 0,05187 s | | Python-Anweisung | 33 / 2841 | 33 | 1 | 0,11914 / 0,11780 s | 0,00439 / 0,00518 s | Alle sechs vollständigen F32-Endtensor-Hashes (Logits und Hidden je Erweiterung), die Fortschrittsfelder und MTP-Offsets 120/2840/2873 stimmen exakt. Die höheren Rust-History-Rohzeiten bleiben sichtbar. Dies sind einzelne instrumentierte Numerikläufe, keine balancierte 2%-Abnahme. Die drei Folge-Anweisungen wurden hier **nur vorgefüllt**: keine drei vollständig generierten Antworten und kein vollständiger SessionBank-/UI-/Harness-Chat werden daraus behauptet. Canary MTPLX/Rust: 120/111 Proben, keine Fehler/Abbrüche; Maximum der gemeinsamen Prefill-Phase (kalter Ping plus warme Suffixe) 0,719/0,589 ms, Ping-Decode 0,161/0,182 ms. Kein UI-Eventloop gemessen. Supervisor-Gesamtzeit 13,374/12,461 s, Peak-Footprint 81.600.772.008/81.307.416.056 Bytes. Alle Modellläufe einzeln, 81920-MiB-/30-s-Start-/45-s-Fortsetzungsbudget und durchgehende 2-s-GPU-Canary. Release-Testbuild, warnings-denied Clippy und Format-/Diffprüfung bestanden. **Schutzkorrektur am Test-Wächter:** Der bisherige Ausgabe-Watchdog konnte durch workerinterne Canary-Meldungen einen Stillstand der eigentlichen Inferenz übersehen. `test-supervisor` leitet diese Meldungen weiterhin vollständig weiter, zählt die bekannten GPU-Canary-/Ressourcen-Messereignisse aber nicht mehr als Fortschritt. JSON wird über Pipe-Lesegrenzen zusammengesetzt; normale Teilzeilen wie Rust-Testbanner bleiben Fortschritt, Pufferung ist begrenzt. CPU-Selbsttests prüfen auch Start-/Fortsetzungsabbruch trotz endloser Canary-Ausgabe und erlauben einen tatsächlich fortschreitenden Lauf über mehrere Timeoutfenster: drei Tests, 2,39 s, bestanden. Neues Release-Binary des Wächters gebaut. Das bleibt ein kooperativer Ausgabe-Wächter, kein Beweis für GPU-Fortschritt aus beliebigen Worker-Logs und keine Garantie gegen einen nicht unterbrechbaren Treiberfehler. Kein neuer GPU-Lauf war dafür erforderlich. Weiter offen am warmen Pfad: SessionBank-Auswahl, Snapshot-/Checkpoint-Restore, Policy-Wechsel AR/MTP, optionale recurrent Boundary-Captures, Vision-Splicing, Cleanup/Repaging und zusätzliche Abort-/AR-Referenzfälle. Der kanonische Pfad bleibt `cfg(test)`, bis seine produktiven Owner-Verträge verbunden sind. Kein Bundle, Commit oder Push. **Trunk-/MTP-Snapshot und Restore, 2026-09-10:** `qwen_mtplx/session_cache.rs` verbindet die vorhandenen Cache-/Arraytypen mit den originalen `snapshot_cache`, `snapshot_cache_lazy_hybrid` und `restore_cache` aus dem gepinnten `mtplx/cache_state.py:4334–4482`. Recurrent/GDN/PLE-Zustände werden wie `_clone_tree` durch lazy Add-zero-Ausdrücke kopiert. Trimmable QSA-Zustände bleiben beim Lazy-Snapshot gehaltene Views; der Restore erzeugt neue mutable Array-Container statt die gespeicherten Container einzusetzen. Die vorhandene Donation-Prüfung schützt die gehaltenen Deskriptoren. Offset, Raw-/Pool-Frontier und Kapazitäten kommen aus dem originalen QSA-State-Setter; abgeleitete Mirrors und Verify-Captures sind keine Snapshot-Blätter. Keine erzwungene Auswertung oder zusätzliche Synchronisation im Snapshot/Restore. Der bestehende Vollmodelltest und sein Original-Oracle wurden um drei echte Snapshot-/Fresh-container-Restores erweitert: lazy / kopiert / lazy, mit 28 / 2720 / 33 Suffix-Tokens. Für sämtliche Cache-Blätter (Dtype, Shape, vollständige F32-Werte) werden gemeinsame SHA256-Belege geprüft, getrennt für Trunk und MTP. Gespeicherte Zustände müssen auch nach der Fortsetzung exakt unverändert sein. Alle sechs finalen Logits-/Hidden-Hashes, Chunk-Fortschritte, History-Offsets und die vorausgehenden 52 Ping-Tokens/19 MTP-Zyklen stimmen. Rohdaten: `local-eval-results/session-cache-20260910.KesHxk/reference.*.log` und `rust.*.log`. Erster Rust-Lauf bestanden in 14,27 s; dabei materialisiert die diagnostische Hashprüfung den Snapshot noch vor dem Restore. MTPLX/Rust: Supervisor 15,102/14,990 s, Lifetime-Peak 81.965.136.024/81.545.557.784 Bytes, Canary 140/139 Proben ohne Fehler. Prefill-Maximum 4,643/6,774 ms, Decode-Maximum 0,507/0,137 ms. Diese instrumentierten Einzelläufe sind kein sauberer Performancevergleich; insbesondere lief jeweils zusätzlich ein CPU-Build beziehungsweise Clippy. Kein UI-Eventloop und keine drei generierten Folgeantworten gemessen. Der strengere Regressionstest liest die gespeicherten Rust-Blätter erst **nach** der Fortsetzung und vergleicht dann mit den unveränderten Original-Belegen vor/nach Mutation. Dieser strengere Lauf (`rust-lazy.*.log`) ist ebenfalls vollständig bestanden: 12,00 s Testzeit, 12,719 s Supervisorzeit, Lifetime-Peak 81.546.377.248 Bytes. Kein paralleler Build/Clippy oder anderes Modell; 117 Canary-Proben, null Fehler, Maximum 3,146 ms. Der rohe OS-Disk-Write-Zähler liegt nahe u64::MAX und ist ungültig; er wird nicht als IO-Leistungswert interpretiert. Alle gespeicherten Blätter und sechs Fortsetzungstensoren stimmen weiterhin exakt mit MTPLX. Damit ist auch Restore ohne diagnostisches Vorab-Materialisieren geprüft, nicht nur der erste, bereits ausgewertete Snapshot-Lauf. Release-Testbuild, gezieltes warnings-denied Clippy für App/Tests/Wächter, `cargo fmt --all -- --check` und `git diff --check` bestanden. Keine Downloads, kein Bundle, Commit oder Push; sämtliche Modellprozesse regulär beendet. SessionBank-Auswahl/Metadaten, Disk-Checkpoints, AR/MTP-Policy-Wechsel und die produktive Owner-Anbindung sind damit noch nicht implementiert. Der neue Executor bleibt testintern; die sechs UI-identischen Paritätsläufe sind offen. **Vollständiger Session-Chat, 2026-09-10:** `session_cache::SessionSnapshot` hält nun Tokenpräfix, finale Logits/Hidden, Trunk-, MTP- und recurrent Boundary-Zustände. `capture_session` und `restore_session` verwenden die echten SessionBank-Payload-Regeln: Lazy-Trunk abhängig von der Bankpolicy, MTP immer per vollständigem `snapshot_cache` und beim Restore ebenfalls geklont, Logits/Hidden beim Speichern und Wiederherstellen jeweils `_clone_tree`. Nicht passende Tokenpräfixe werden vor Mutation abgelehnt. Dies ist die Zustandsübergabe im Executor, noch keine vollständige SessionBank mit Identitätsauswahl, Eviction, SSD-Cold-Tier und UI-Anbindung. `tools/mtplx-execution-reference.py --chat --readme README.md` nutzt jetzt die **originale SessionBank** zusammen mit `generate_ar` beziehungsweise `generate_mtpk`: README-Summary → vollständige Story → Python-Primzahlfunktion, mit allen vorherigen Ausgabetokens im nächsten Prompt. Alle drei Antworten enden natürlich; kein Tokenlimit als Testabschluss, keine Tools/Skills oder Downloads. Seed 0, Temperatur 0,6, top-p 0,95, top-k 20, Low-Thinking, 2048er Prefill, SSD-PLE, MTP-D3/committed/batched, originale Serverdefaults. Der bestehende Referenz-Runner wurde erweitert, kein weiterer Modellpfad gebaut. **Erst durch die Session-Reproduktion sichtbar gewordene Abweichung:** Der erste Rust-MTP-Chat (`rust-mtp.*.log`) bricht am achten ausgegebenen Token des Summary-Turns ab: Soll 3766, Ist 19953. MTPLX aktiviert mit SessionBank `_gdn_boundary_capture_enabled` und verfeinert den letzten Prefill-Body-Span mit `_prefill_spans_with_tail_grid`: nicht 2048+699, sondern **2048+256+256+187**, danach das letzte Token separat. Die bisherigen isolierten Generator-/Suffixfixtures hatten keine SessionBank und prüften deshalb diesen Requestpfad nicht. Die globale Chunkgröße wird ausdrücklich nicht reduziert. Der gemeinsame Rust-Prefill-Treiber benutzt jetzt dieselbe Spanaufteilung bei aktivierter Boundary-Policy. Nach dem History-Update werden nur recurrent GDN/PLE-Zustände geklont; vorhandenes Hidden wird über `contiguous` ausgewertet und gehalten, wie `detach_array_leaf(..., mode="contiguous_eval")`. Geometrische Retention begrenzt die Snapshotzahl. Finale Sessions erben diese Grenzen und ersetzen im geprüften geradlinigen Chat ältere Präfixeinträge. Explizite Mandatory-Edges werden vom gemeinsamen Spanhelfer unterstützt; die produktive Stable-Prefix-/Near-Prefix-Auswahl ist weiterhin offen. **Nach Korrektur beide vollständigen Chats bestanden:** jede ausgesendete Token-ID, jedes natürliche EOS, alle finalen vollständigen F32-Logit-/Hidden- Hashes, alle MTP-Zyklen (inklusive Context-Copy), MTP-Offsets und geerbten Grenzpositionen sind exakt wie MTPLX. Die vier Grenzen bleiben in allen Turns 2048/2304/2560/2747. Rust hält Prompt-Snapshots während Decode und nutzt echte Snapshot-/Restore-Container für die folgenden Turns; kein stiller Cold-Replay. | Modus / Turn | Prompt | davon wiederverwendet | Output einschließlich EOS | |---|---:|---:|---:| | AR Summary | 2748 | 0 | 635 | | AR Story | 3411 | 3383 | 1347 | | AR Python | 4791 | 4758 | 266 | | MTP Summary | 2748 | 0 | 466 | | MTP Story | 3242 | 3214 | 1394 | | MTP Python | 4669 | 4636 | 326 | Rohdaten: `local-eval-results/session-chat-20260910.jT3hf5/`. Maßgeblich `reference-{ar,mtp}-boundary.*.log` und `rust-{ar,mtp}-boundary.*.log`; ursprüngliche Referenzen und der fehlerhafte Rustlauf bleiben erhalten. Die ergänzte MTP-Referenz liefert gegenüber ihrem ersten Lauf unveränderte Tokens, Zyklen und Endtensor-Hashes in allen drei Turns. Ausgaben wurden gelesen: zusammenhängende Summary und vollständige Story ohne Rückfrage, Python enthält die erwartete `is_prime`-Funktion mit fünf Assertions. Generierter Code wurde dabei nicht ausgeführt; das ist noch keine automatische inhaltliche Benchmark-Abnahme. Alle Modellläufe einzeln unter 81920 MiB / 30-s-Start / 45-s-Fortsetzung und durchgehender 2-s-GPU-Canary. Keine Canaryfehler. AR MTPLX/Rust: 661/550 Proben, Prefill-Maximum 2,342/1,653 ms, Decode-Maximum 0,935/0,786 ms; Lifetime-Peak 82.686.638.304/82.424.002.208 Bytes. MTP: 566/561 Proben, Prefill-Maximum 97,546/0,810 ms, Decode-Maximum 0,540/0,715 ms; Lifetime-Peak 83.454.868.352/82.950.518.912 Bytes. Kein GUI-Eventloop wurde gemessen. **Keine 2%-Freigabe:** instrumentierte numerische Läufe ohne separaten Warmup, bei Referenzläufen teilweise paralleler CPU-Testbuild. Original-`elapsed_s` enthält andere Phasengrenzen als der innere Rust-Decode-Zähler. Trotzdem bleibt ein konkreter Performanceverdacht sichtbar: MTP-Story benötigt in Rust bereits 31,663 s Decode, gegenüber 29,938 s für den gesamten entsprechenden Referenz-Generierungsaufruf. Das wird nicht durch die funktionale Gleichheit oder die kurzen Canaryzeiten als erledigt behandelt. Saubere gepaarte Performanceabnahme folgt am vollständig integrierten UI/Harness-Pfad. Bestehende modellfreie Prefill-Regressionen unverändert bestanden: 656 MTP- und 505 AR-Receipts, zwei Tests in 0,32 s unter 2048-MiB-/15-s-Wächter. CPU-Policytest prüft Tail-Grid/Mandatory-Edges und geometrische Retention; die tatsächliche gepinnte Pythonfunktion lieferte zusätzlich exakte Cap-8-/64- Belege. Die native Ganzzahlrechnung sättigt das Potenzprodukt, um Python- Integersemantik auch bei großem Retentionslimit zu erhalten. Abschließender Release-Testbuild, Cap-8-/64-Policytest, gezieltes warnings-denied Clippy für App/Tests/Wächter sowie Format-/Diffprüfung bestanden. Die abschließende Änderung betrifft nur den Überlaufschutz bei großem Retentionslimit; die Vollmodellläufe benutzen vier Grenzen unter dem unveränderten Limit acht. Alle Modellprozesse sind regulär beendet. Kein Bundle, Commit oder Push. **Gemeinsamer Token-Turn-Einstieg, 2026-09-10:** `Execution::session_turn` in `qwen_mtplx/session_cache.rs` übernimmt jetzt Cold-/Restore-Prefill, AR-/MTP-Decode, die während Decode gehaltene Prompt-Snapshot-Referenz und den sicheren finalen Snapshot. Der vollständige Chat-Test ruft diesen Einstieg auf; seine zuvor eigene Prefill-/Decode-Steuerung ist entfernt. Vorhandene Treiber bleiben unverändert, keine neuen Kernel oder Dependencies. Dies bereitet die gemeinsame Produktanbindung vor, aktiviert sie aber noch nicht: `qwen_mtplx` bleibt `cfg(test)`. Finale MTP-Arrays sind nur bei angefordertem Capture und ohne Pending-Token oder Capture-Fehler bankfähig. Ein fehlgeschlagener Snapshot wird separat gemeldet, nicht als Verlust einer fertig generierten Antwort. Der CPU-Test `mtplx_session_final_state_requires_capture_and_safe_cache` prüft fehlendes, abgeschaltetes, erfolgreiches und fehlgeschlagenes Capture sowie den Pending-Fall; er erzeugt nur unallokierte Array-Deskriptoren, keine GPU-Arbeit. Der unveränderte Promptzustand bei null MTP-Ausgabetokens bleibt entsprechend der Referenz erlaubt, wenn Capture ausdrücklich angefordert ist (`generation.py:12291`). Beide vollständigen Chats gegen die vorhandenen `reference-{ar,mtp}-boundary` Belege erneut bestanden: alle Tokens einschließlich natürlichem EOS, finale Logit-/Hidden-Fingerprints, Cache-Präfixe und Boundary-Positionen; zusätzlich alle MTP-Zyklen und History-Offsets. Keine Referenz neu erzeugt oder Erwartung geändert. Rohdaten: `local-eval-results/session-entry-20260910.F1yAZH/{capture,ar,mtp}.*.log`. | Modus / Turn | Ausgabetokens inkl. EOS | Prefill s | Decode s | | --- | ---: | ---: | ---: | | AR Summary | 635 | 6,213481 | 12,075834 | | AR Story | 1347 | 0,105876 | 25,776388 | | AR Python | 266 | 0,124386 | 5,102924 | | MTP Summary | 466 | 5,956198 | 6,339998 | | MTP Story | 1394 | 0,114543 | 27,345384 | | MTP Python | 326 | 0,154080 | 4,225220 | Alle Prozesse einzeln mit `test-supervisor`: CPU-Test 2048/15/15, Modelltests 81920/30/45, SSD-Ngram, originale Server-Overrides, Chunk2048, ohne Drosselung. Der permanente 100-ms-GPU-Canary hatte AR/MTP 516/468 Proben, keine Fehler; Prefill-Maxima 0,747/0,727 ms, Decode 0,559/0,540 ms, Laden 3,229/11,644 ms. Peak-Footprint 82.422.937.008/82.943.817.736 Bytes; Supervisor 55,407/50,261 s, beide regulär beendet. Kein CPU-Build parallel zu den Modellläufen. Diese instrumentierten Kalt-/Fortsetzungsprüfungen ohne vorgeschalteten Warmup sind weiterhin **keine** saubere 2%-Performanceabnahme und messen keinen GUI-Loop. Release-Testbuild (`cargo test --release --offline --bin ds4-server --no-run -j 1`), gezieltes Clippy mit `-D warnings`, Format-/Diffprüfung bestanden. Testbinary SHA256: `14e13eaa14e810af12ad149e7b1ebe6bf231cef8129d7c951a5b4da661e74441`. Weiter nötig für den Produktanschluss: Session-Auswahl/Identität und Disk-Payload, Erhalt von Prefill-Bankeinträgen bei Abbruch, Abbruch-/Text-Stop-Ausgänge im Turn-Adapter, Power-Pausen sowie gemeinsame Metriken. Keine Umschaltung auf den neuen Executor, bevor diese bestehenden `Generator`-Verträge angeschlossen sind. **Gemeinsame produktive Textausgabe, 2026-09-10:** `Generator::generate_inner` verwendet jetzt `GeneratedText` für den bisherigen UTF8-/Thinking-/Stop-Zustand. Die vorhandenen Helfer `append_generated_bytes`, `emit_safe_text` und `flush_generated` werden unverändert wiederverwendet. Die scalar Decode-Schleife enthält keine eigene Kopie dieser Zustandsübergänge mehr. EOS, Abbruchprüfung, Completion-Zähler und Cache-Gültigkeit bleiben unverändert beim Generator. Keine Änderung an Sampling, Prefill-Größe, GPU-Dispatch oder Power-Policy; keine zusätzliche Dependency oder Queue. Der kanonische Vollmodell-Chat verwendet exakt dieselbe Textausgabe im Token-Callback, mit dem installierten Produkt-Tokenizer. Zusätzlich zur bisherigen Token-/Zyklus-/Cache-Parität prüft er jetzt Thinking- und Antworttext sowie deren gestreamte Chunks bytegenau gegen `chat_turn.text` der bestehenden MTPLX-Belege. Alle sechs Turns erneut bestanden; Referenzen und Erwartungen unverändert. Zwei CPU-Regressionstests (`generated_text_`) prüfen geteilte UTF8-Sequenzen, unvollständige Sequenzen beim Drain/Phasenwechsel, Thinking-Ereignisse, einen tokenübergreifenden Text-Stop und duplikatfreies abschließendes Flushen. Rohdaten: `local-eval-results/shared-emission-20260910.IrS1L4/`: `text-matched.*.log` (2 tatsächliche Tests), `ar.*.log`, `mtp.*.log`. Das vorausgehende `text.*.log` traf mit falsch qualifiziertem Filter null Tests und ist ausdrücklich kein Testnachweis. | Modus / Turn | Thinking / Antwort Bytes | Prefill s | Decode s | | --- | ---: | ---: | ---: | | AR Summary | 194 / 2514 | 4,667441 | 12,064467 | | AR Story | 226 / 5774 | 0,105925 | 25,786883 | | AR Python | 142 / 711 | 0,125289 | 5,135448 | | MTP Summary | 174 / 1837 | 5,230820 | 6,341459 | | MTP Story | 270 / 5817 | 0,114802 | 27,293845 | | MTP Python | 203 / 875 | 0,147034 | 4,231167 | Unveränderte sequentielle Supervisor-Grenzen: CPU 2048/15/15, Vollmodell 81920/30/45, SSD-Ngram, Server-Overrides, Chunk2048, ungedrosselt, 100-ms-Canary. AR/MTP: 504/460 Proben ohne Fehler oder 2-s-Stall; Prefill-Maxima 8,309/0,683 ms, Decode 0,620/0,535 ms, Laden 3,334/4,606 ms. Peak-Footprint 82.497.910.432/83.026.982.920 Bytes; Supervisor 53,920/49,404 s, regulär beendet. Keine parallelen Builds während der Modelltests. Release-Testbuild, gezieltes Clippy mit `-D warnings`, Format-/Diffprüfung bestanden. Testbinary SHA256: `e02b2d809197d224a56423b029f8e8dbc66c4f35a0f3cdbe727de019d8b81fa8`. Dies verbindet die produktive **Ausgabe-Verarbeitung**, noch nicht den kanonischen **Inferenz-Executor** mit UI/`model-eval`. Letzterer bleibt `cfg(test)`. Session-/Disk-Adapter, Whole-Turn-Abbruch/Stop, Power und Metriken sind weiter anzuschließen. Die Messungen sind instrumentierte Funktionsregressionen ohne vorgeschalteten Warmup, keine 2%-Abnahme und kein GUI-Eventloop-Nachweis. Kein Bundle, Commit, Push oder Download. **Qwen-Checkpoint-Payload nach MTPLX, 2026-09-10:** Der neue `qwen_mtplx/session_codec.rs` bildet für die vorhandenen typisierten Qwen-Zustände `cache_bank/codec.py` ab: JSON-Baum mit Tuple-/List-/None-Metadaten, Trunk, Logits, Hidden, MTP-Head und innere GDN-Grenzen. Die Blob-Namen folgen der originalen Besuchsreihenfolge. Axis-2-Tensoren werden ab `2 * block_size` in Blöcke zerlegt (Default der Referenz 256, null wird zu eins). Schreiben kann über denselben Callback entweder gestaged oder direkt auf Disk erfolgen; die fertigen Bytevektoren werden übergeben, nicht für den Speicher-Handler kopiert. `bytes(memoryview(array))` wird nach der Auswertung mit vorhandenen Array-/Buffer-Helfern in logischer C-Reihenfolge gelesen, auch für negative, transponierte und Broadcast-Strides. Kein zusätzlicher GPU-Cast/Contiguous- Dispatch zum Export. BF16 bleibt als rohe 16-Bit-Darstellung erhalten; Restore verwendet den ursprünglichen View-/Reshape-/Concatenate-Pfad. Der skalare Referenzfall Shape `[]` wird beim Restore wie im Original `[1]`, nicht heimlich korrigiert. Abbruch wird vor jedem Tensor und jedem Block geprüft. Vollständiger Payload-Restore und separat aufrufbarer Boundary-Restore bilden die zwei originalen Routen ab. Ein exakter Restore kann Boundary-Blobs vollständig überspringen; späterer partieller Restore liest ausschließlich diese Blobs. Die separat gebatchte Boundary-Auswertung und anschließende Gesamt-Auswertung bleiben erhalten. Ältere Payloads ohne `gdn_boundaries` und Records ohne `hidden_last` werden wie in der Referenz akzeptiert. Ungültige Blob-Namen (einschließlich Pfad-Traversal), falsche Bytezahlen und Lesefehler werden abgewiesen. Referenz unverändert gepinnt auf `e652d55e2652137a4abcf1312357abbf3eb9d692`. `tools/mtplx-session-codec-reference.py` verwendet dessen tatsächliche `encode_payload`-/`decode_payload`-Funktionen mit kleinen synthetischen Tensoren, keine Modellgewichte. Blockgrößen 0/256/1024 ergeben 1568/19/13 Blobs, jeweils 41.480 Payload-Bytes. Alle **1600 Blobs byteidentisch**, ebenso Payload-Spec, restaurierte Datentypen/Shapes/Hashes und erneute Serialisierung. Der Rust-Test liest die originalen Python-Dateien, nicht nur seine eigenen Writes. Zusätzlich geprüft: selektive Blob-Zugriffe, Legacy-Records, Lesefehler, ungültige Namen, abgeschnittene Daten und Abbruch vor dem zweiten Block nach genau einem Write. Belege: `local-eval-results/session-codec-20260910.GQsCzv/`. Maßgebliche finale Fixtures unter `compat/`, Logs `reference-compat.*.log` und `rust-ready.*.log`; `rust.*.log` ist der vorausgehende erfolgreiche Grundvergleich. Alle Programme einzeln unter `test-supervisor 2048 15 15`, keine geladenen Modelle oder Downloads. Finaler Rust-Test: **1 Test bestanden**, 0,24 s Testzeit, 0,967 s Supervisor; Peak Physical 171.524.912 Bytes. Referenz-Supervisor 0,315 s, Peak 156.140.192 Bytes; der winzige Referenzlauf überlappte einen CPU-Build. Diese Werte sind Funktionsdiagnostik, **kein Performance-A/B**. Release-Testbuild, gezieltes Clippy mit `-D warnings`, Format-/Diffprüfung bestanden; alle Tests beendet. **Import-Korrektur nach vollständigem Caller-Trace (10.09.):** Die vorige Forderung, hier einen Zero-Copy-Host-Owner zu portieren, war falsch. Zwar besitzt `python/src/convert.cpp:190,259` einen `copy=None`-Übernahmepfad. Aber der tatsächlich von `mtplx/cache_bank/codec.py:395–409` verwendete `mx.array(...)`-Konstruktor übergibt in `python/src/array.cpp:311` ausdrücklich `create_array(v, t, true)`; `convert.cpp:706–722` reicht dieses **copy=true** an `nd_array_to_mlx` weiter. Deshalb kopiert der Codec auch seitenalignierten Host-Speicher. Der Default eines internen Helfers ist kein Beleg für das Verhalten seines konkreten Aufrufers. Die modellfreie Probe `tools/mtplx-host-import-reference.py` bestätigt direkt in der unveränderten installierten MTPLX-Runtime: alignierte 16-KiB-, unalignierte 16-KiB-, kurze 17-Byte- und leere Eingaben werden nicht übernommen; keine hält den NumPy-Host-Owner fest. Nach der Freigabe liegen 16384/16384/17/0 Bytes im Pool. Belege: `local-eval-results/host-import-20260910.dfNdNK/reference-verified.stdout.log` (finale Probe mit Assertions; `reference-default.stdout.log` war der erste erfolgreiche Lauf). Der erste Versuch mit einem `copy`-Keyword wurde vom Python-Konstruktor abgewiesen; `reference.stdout.log` / `reference.stderr.log` sind **kein erfolgreicher Nachweis**. Die reale Abweichung war das Umgehen des kanonischen Allocators außerhalb einer GPU-Scope. `decode_tensor` kopiert nun ausdrücklich über `streams.allocator()`; leere Tensoren behalten den bestehenden null-storage-Descriptor. Es wurde **kein** Zero-Copy-/Host-Lifetime-Pfad oder neuer nativer Allocator eingeführt. Der gezielte Rust-Test prüft Referenzgrößen, Copy-Semantik, View-/GPU-Hold-Lebensdauer, Pool-Rückgabe und Wiederverwendung beim zweiten Import. **Beide Codec-Tests bestanden**: `mtplx_session_codec_host_import_matches_reference` und `mtplx_session_codec_matches_original_blobs_and_restore` (weiterhin alle 1600 Blobs). Der neue Test läuft ausdrücklich ohne aktive GPU-Scope und würde bei der alten `scalar_buffer`-Route an der aktiven Pool-Belegung scheitern. Nachweise im selben Verzeichnis: `rust.stdout.log` / `rust.stderr.log`. Supervisor 2048 MiB / Start 15 s / Fortschritt 15 s; keine Modelle, Downloads oder parallelen Builds während der Proben. Beide Tests 0,24 s, Supervisor 0,938 s, gemessener Peak Physical 168.657.664 Bytes. Der 0,105-s-Pythonlauf ist für eine belastbare Peak-Speichermessung zu kurz; keine Performance-A/B-Aussage. Release-Testbuild (`/tmp/ds4-host-import-build.log`), gezieltes Clippy mit `-D warnings` (`/tmp/ds4-host-import-clippy.log`), Format-/Diffprüfung bestanden; alle Prozesse regulär beendet. Testbinary SHA256: `39a0165f0e0aa26b6a4db2075cb3f59786bef9a21db2395c381c46ecdeb4ef6e`. Die native Bridge und Buffer-Lifetime-Implementierung wurden in diesem Schritt nicht verändert. Die Python-Extension der unveränderten Referenz hat SHA256 `5ff77c777a73864d2af86defd61b141467746636f0047b76b66a7ae645fa12fb`. **Qwen-Request-Grenze und abbrechbare Ausgabe, 2026-09-10:** `qwen_mtplx/request.rs::Execution::generate_text` benutzt ausschließlich `session_turn` für Prefill/AR/MTP und liefert das bestehende `GenerationOutput` mit dem gemeinsamen `GeneratedText`. Es gibt keinen zusätzlichen skalaren Sampling-/Decode-Loop. Tokenzähler schließen wie in der UI EOS aus, während der Sessionzustand die vollständige Tokenfolge inklusive EOS behält. UTF-8, Thinking-Wechsel und Text-Stops verwenden dieselbe Ausgabe-Verarbeitung wie die UI. Ein tatsächlich im Adapter beobachteter Abbruch oder Text-Stop liefert den bereits erzeugten Text, aber **keinen finalen Sessionzustand**. GPU-/IO-/Observer- Fehler werden nicht als erfolgreiche Abbrüche verschluckt. Der Adapter versucht nicht, einen möglicherweise vorausgerechneten AR-/MTP-Cache nach einem Stream-Stop als vollständigen Chat zu speichern. Die nächste Generierung restauriert einen gültigen Bankeintrag. Die Referenz speichert den Prompt bereits vor Decode (`generation.py::_maybe_store_prefix_snapshot`, Zeilen 3888–3973); bisher hielt Rust diesen Snapshot nur auf dem `session_turn`-Stack und verlor ihn bei Fehlern. Nun übernimmt ihn ein Storage-Callback vor `TurnProgress::Decode`, sodass er auch nach einem Abbruch beim Caller verbleibt. Ein fehlgeschlagenes Prefix-Store bleibt wie in MTPLX nichtfatal (`prefix_snapshot_error`). Der vorhandene Vollmodell-Chat-Test läuft jetzt durch diesen Request-Adapter, nicht mehr durch einen separat im Test zusammengesetzten Text-Callback. AR und MTP jeweils **1 Test bestanden**: alle drei natürlichen Antworten, sämtliche Tokens und finalen Fingerprints, Boundary-Positionen und zusätzlich alle MTP-Zyklen und Head-Offsets unverändert zur gespeicherten Referenz. Zusätzlich je Modus: Abbruch vor Prefill ohne Ausgabe/Store, echter Observer- Fehler bleibt Fehler, Abbruch nach erster Ausgabe erhält Teiltext und Prompt- Snapshot, Literal-Stop leakt keinen Text, fehlgeschlagener Prefix-Store erreicht trotzdem den Decode-Einstieg. Die zwei folgenden regulären Chat-Turns restaurieren weiterhin exakt den gültigen Finalzustand, nicht die unterbrochenen Cache-Reste. Belege: `local-eval-results/request-turn-20260910.lh9PZ4/{ar,mtp}.{stdout,stderr}.log`. Nur installierte Qwen-Gewichte, sequentiell, kein paralleler Build; unveränderte Referenz-Overrides, SSD-Ngram, Chunk2048, ungedrosselt, Supervisor 81920/30/45, 100-ms-GPU-Canary mit 2-s-Abbruch. AR/MTP 601/529 Canary-Proben, null Fehler/Stalls; Prefill-Maxima 7,005/3,794 ms, Decode-Maxima 0,834/1,241 ms. Die zusätzlichen Abbruch-Proben zwischen den regulären Turns liegen im äußeren Testabschnitt `finishing`, nicht in einer nachgebildeten GUI-Phase. Kein GUI-Eventloop-Nachweis. Peak Physical 82.724.992.648/83.067.795.392 Bytes; beide Supervisoren regulär beendet. | Modus / Turn | Prefill s | Decode s | | --- | ---: | ---: | | AR Summary | 10,480830 | 12,810777 | | AR Story | 0,111735 | 27,830894 | | AR Python | 0,141198 | 5,605803 | | MTP Summary | 9,687827 | 6,756337 | | MTP Story | 0,122406 | 29,269802 | | MTP Python | 0,154803 | 4,568898 | Diese Zeiten sind gegenüber mehreren vorherigen Diagnostikläufen schlechter, insbesondere der kalte Prefill. **Keine Performance-Parität oder unveränderte Performance behauptet:** kein Warmup, keine zeitnah gepaarte Referenz und zusätzliche Abbruch-Proben. Die Ursache der Zeitdifferenz ist damit nicht belegt und muss in der kontrollierten End-to-End-Abnahme geprüft werden; die Funktionsprüfung darf sie nicht als erledigt deklarieren. Release-Testbuild und gezieltes Clippy mit `-D warnings` (`/tmp/ds4-request-{build,clippy}.log`), Format-/Diffprüfung bestanden. Testbinary SHA256 `6c44e2150e9bc34e362d73fb5dd688357ca71e5f7fbed3179c9510ad42b12959`. Der Request-Adapter bleibt Teil des `cfg(test)`-Ports. **Noch keine produktive Umschaltung:** `Generator`/UI/`model-eval` müssen erst denselben Owner einschließlich Session-Auswahl/Identität/Disk-Store, Power-Pausen und laufender gemeinsamer Metriken benutzen. Die sechs 2%-Vergleiche bleiben vollständig offen; kein Bundle/Commit/Push. **Gemeinsame Fortschritts-/Decode-Messung und frischer Golden-Master-Abgleich, 10.09.:** `request::RequestProgress` liefert nun den bestehenden UI-/Runtime-Callback `(used, limit, Option)` ab dem gecachten Frontier, für Prefill und jeden ausgegebenen Token. Der warme Backend-Fortschritt ist bereits absolut; gecachte Tokens werden nicht doppelt addiert. Der Adapter nutzt `Metrics` für Prefix-Reuse und denselben `DecodeTimer` wie die UI. AR und MTP melden ihre Decode-Endgrenze jetzt **vor** finalem Token-/Cache-Capture; bisher kam `TurnProgress::Finalize` erst danach. Normale Ergebnisse übernehmen die gemessene Backend-Decode-Dauer, Fehler/Abbruch verwenden weiterhin die gemeinsame RAII- Zeitmessung. Weder Sampling noch Shader/Command-Submission wurden verändert. Zwei modellfreie Tests bestanden: `qwen_request_progress_uses_ui_frontiers_and_decode_timer` und `decode_timer_excludes_later_work_and_resets_between_requests`. Die AR-/MTP- Referenz-Chats samt Abbruchfällen jeweils erneut bestanden; zusätzliche Assertions prüfen Start-/Endfrontier, jeden Token-Fortschritt, Kontextlimit und die exakt im gemeinsamen Metrikobjekt gespeicherte Decode-Dauer. Belege: `local-eval-results/request-progress-20260910.DvrBll/{timing,ar,mtp}.*.log`. AR/MTP: 607/529 Canary-Proben, keine Fehler/Stalls; Prefill-Maxima 10,841/0,906 ms, Decode 0,690/0,901 ms, Finishing 0,789/0,580 ms. Peak Physical 82.719.667.704/83.067.533.128 Bytes. Negative/übergelaufene OS-Disk-Write-Zähler in diesen Logs sind ungültig und werden nicht als IO-Leistung interpretiert. Die wiederholten kalten Prefills nahe 10 s wurden unmittelbar am unveränderten MTPLX-Master gegengeprüft. Der erste AR-Referenzlauf benötigte 11,367 s, der zweite 9,664 s: **keine belegte Rust-spezifische Ursache für den Abstand zu älteren ~5–6-s- Läufen**, aber auch keine Erklärung der äußeren Ursache allein aus diesen Proben. Dabei wurde die Referenz-Metrikgrenze vollständig nachverfolgt: `generation.py::_generation_rate_fields` zieht Prefill, Restore und sonstige Prompt-Phase ab; `elapsed_s` ist dagegen die Gesamtspanne einschließlich Prefill. Der Recorder gibt nun direkt `decode_elapsed_s`, `decode_tok_s` und `prompt_state_total_time_s` aus, statt einen Vergleich mit reiner Rust-Decode-Zeit aus der Gesamtzeit ableiten zu müssen. Modellfreier Original-Stats-Gegencheck (`reference-rates.*.log`): 14 s Gesamtzeit minus 10 s Prefill, 1 s Restore, 1 s sonstige Vorbereitung = 2 s Decode und 50 Token/s bei 100 Tokens. Zeitnaher diagnostischer Vergleich, **kein Warmup/Median und keine produktive UI-/Harness-Abnahme**. Beide Seiten dieselben installierten Gewichte, Server- Overrides, Chunk2048, SSD-Ngram, niedriges Thinking, ungedrosselt/100 %, durchgängiger 100-ms-Canary mit 2-s-Abbruch, Supervisor 81920/30/45, sequentiell ohne CPU-Builds. README-Prompt-SHA256 auf beiden Seiten `69a37cf788e427fd384558517092e9a2a222f33910be63b48175516bf15ad84d`. Neue Referenz-Receipts stimmen nach Entfernung ausschließlich der Zeitfelder mit den bisherigen Tokens, Texten, Cache-Fingerprints, Boundaries und MTP-Zyklen überein. Quellen: `reference-{ar,mtp}-rates.{stdout,stderr}.log` im selben Verzeichnis. | Qwen / Prompt | Prefill Rust / MTPLX s | Decode Rust / MTPLX Token/s | Rust-Decode-Differenz | | --- | ---: | ---: | ---: | | AR Summary | 9,950 / 9,664 | 48,91 / 50,22 | −2,60 % | | AR Story | 0,113 / 0,119 | 48,03 / 47,02 | +2,16 % | | AR Python | 0,141 / 0,140 | 47,08 / 46,85 | +0,48 % | | MTP Summary | 9,840 / 12,351 | 69,07 / 66,56 | +3,78 % | | MTP Story | 0,121 / 0,125 | 47,89 / 45,83 | +4,49 % | | MTP Python | 0,158 / 0,154 | 72,32 / 69,03 | +4,77 % | Die Raten verwenden auf beiden Seiten Tokens inklusive EOS; die UI-Completion- Zahl bleibt unverändert ohne EOS. Positiv bedeutet schneller. AR Summary verfehlt in diesem Einzelvergleich 98 % der Referenzgeschwindigkeit; außerdem sind einzelne Prefill-Vergleiche außerhalb 2 %. Das Gesamtziel ist damit ausdrücklich **nicht** erfüllt. Native MTP-Akzeptanz (ohne Context-Copy-Zyklen), identisch in beiden Ports: Summary 301/444 = 67,79 %, Story 746/1920 = 38,85 %, Python 225/279 = 80,65 %. Das passt zum geringen MTP-Nutzen bei der Story und erklärt, warum kein pauschaler Speedup vorausgesetzt werden darf; es ersetzt keine Zerlegung der einzelnen Kosten. Die frischen Referenzen hatten 602/592 Canary-Proben ohne unvollständige Probes, maximal 3,066/2,516 ms über alle Phasen. Alle Prozesse sind regulär beendet. Release-Testbuild, Test- und Produktions-Clippy mit `-D warnings`, Format-/Diffcheck bestanden (`/tmp/ds4-request-progress-{build,clippy,production-clippy}.log`). Testbinary SHA256 `cfc781c74406ecef37d27c77ed9f204c6480b8326db1c2f14b1c277fae432eaa`. Offen: produktiver Owner/Session-Store, gemeinsame Executor-Verdrahtung und echte Power-Pausen unter 100 % (bei AR-Lookahead genügt Schlafen im Token-Callback nicht), danach warme wiederholte Abnahme aller drei Modelle mit/ohne Spekulation. Dieser Schritt fügt keine Warte-/Flushpunkte bei 100 % ein und erklärt den Test-Port nicht zur produktiven UI-Ausführung. Kein Bundle, Commit oder Push. **Backend-explizite Allokation als Integrationsvoraussetzung, 10.09.:** `gpu::Buffer::{bytes,untracked}` hatten zuvor unter `cfg(test)` automatisch die MTPLX-Rundungs-/Pool-Policy verwendet, während Produktbuilds direkt DS4 allozierten. Dieser versteckte Backendwechsel ist entfernt. DS4/GLM und der alte Qwen-Executor verwenden dieselben nativen Allokationsfunktionen unabhängig vom Buildtyp. Alle Aufrufe im kanonischen Qwen-Graph und seinen Fixtures wählen ausdrücklich `mtplx_bytes`, `mtplx_untracked` oder `mtplx_floats`; Rundung, leere Deskriptoren, aktiver Pool und GPU-Lebensdauer bleiben für diesen Pfad unverändert. Keine neue Allokator-Abstraktion, kein geänderter Kernel und keine Scheduling-/Power-Änderung. Neun überwachte modellfreie Tests bestanden: vier Bridge-/Lebensdauerprüfungen einschließlich der neuen Backend-Isolation innerhalb und außerhalb eines Qwen- Scopes, vier vorhandene Allokator-Referenzprüfungen und die Encoder-/Pool-Anbindung. Die neue Prüfung weist insbesondere nach, dass DS4-Allokationen keine MTPLX- Rundung übernehmen und auch bei aktivem Qwen-Scope dessen Pool nicht beanspruchen. Rohdaten: `local-eval-results/explicit-allocator-20260910.olnx1y/` mit `allocation`, `allocator` und `encoder` stdout/stderr. Test- und Produktions-Clippy mit `-D warnings`, Release-Testbuild, Format- und Diffprüfung bestanden. Build-/Clippy-Logs: `/tmp/ds4-explicit-allocator-{build,clippy,production-clippy}.log`. Testbinary SHA256 `d070eaa625a15a8d1abc6c4b23a0b28b057495b05e8417c732ed8cedbfc32cc4`. Anschließend beide vollständigen Qwen-Referenz-Chats einschließlich der vorhandenen Abbruch-/Text-Stop-/Cache-Fehlerfälle bestanden (`ar`/`mtp` stdout/stderr im selben Verzeichnis). Unveränderte Referenzen `session-chat-20260910.jT3hf5/reference-{ar,mtp}-boundary.stdout.log`, installierte Gewichte, Power100, Chunk2048, SSD-Ngram, sequentiell unter Supervisor 81920/30/45 und durchgängigem 100-ms-Canary; keine neuen Downloads. Referenztokens, Texte, Cache-/Boundary-Zustände, MTP-Zyklen und gemeinsame Fortschritts-/Decode- Metriken unverändert korrekt. AR/MTP: 604/551 Canary-Proben, keine Fehler oder Stalls; GPU-Completion-Maximum Prefill 2,026/2,697 ms, Decode 0,658/1,175 ms. Peak Physical 82.718.471.720/83.064.911.928 Bytes; Supervisor-Ende nach 62,657/58,785 s, beide exit 0. Diese kalten Einzel-Regressionsläufe sind weder ein frischer gepaarter Performancevergleich noch die UI-/Harness-Endabnahme. **Gemeinsame Modell-Metadaten vom alten Qwen-Executor entkoppelt, 10.09.:** `engine::ModelRef::Qwen` verweist jetzt auf `QwenMetadata`, nicht mehr auf den alten `QwenModel` mit dessen Gewichts-Mappings und PLE-Leserpool. Tokenizer, Chat-/History- Rendering, Fortsetzung, Stop-/Thinking-Erkennung, Modellübersicht und Checkpoint- Identität liegen in dieser gemeinsamen Struktur. Der bestehende Produkt-Executor delegiert unverändert dorthin. Der separate Metadaten-Lader verwendet dieselbe Artefakt-/Header-/Tokenizer-Validierung, öffnet aber keine Gewichts-Mappings, GPU-Kontexte oder PLE-Leser; der kanonische Controller benötigt dafür keine zweite Instanz des alten Modell-Executors. Sein vollständiger Chat-Test verwendet bereits diesen Loader. Prefill-/Decode-Controller, Kernel und Persistierungsformat wurden in diesem Schritt nicht verändert. Vier überwachte Metadaten-/Artefakttests bestanden, darunter `pinned_qwen_metadata_matches_product_without_executor_state`: mit/ohne MTP gleiche Übersicht (2469/2527 Tensoren), gleiche Checkpoint-Identität, Direct-/Low-/XHigh- Rendering, History und Fortsetzung einschließlich `skip_previous_eos`, Stop- und Tokenbyte-Verhalten; zusätzlich bestehende Literal-Goldens und Fail-Closed-Prüfungen. Rohdaten: `local-eval-results/qwen-metadata-20260910.qJ4vq2/metadata.{stdout,stderr}.log`. Test-/Produktions-Clippy mit `-D warnings`, Release-Testbuild, Format-/Diffcheck bestanden. Logs: `/tmp/ds4-qwen-metadata-{clippy,production-clippy,build}.log`. Testbinary SHA256 `067370d61a22354d8de9ffe7bbd98d150b647b75b8b617dd7e96447d6465c2d2`. Die vollständigen AR-/MTP-Chats mit dem separaten Metadaten-Lader bestanden danach ebenfalls: gleiche eingefrorene Referenzen und Supervisor-/Power-/Canary-Einstellungen wie oben, unveränderte Token-/Text-/Cache-/Boundary-/MTP- und Abbruch-Assertions. Rohdaten `ar`/`mtp` stdout/stderr im selben Verzeichnis. AR/MTP: 571/553 Canary-Proben, keine Fehler oder Stalls; maximale GPU-Completion im Prefill 2,261/2,347 ms, im Decode 1,049/0,548 ms. Peak Physical 82.622.526.968/83.166.132.544 Bytes; Supervisor-Laufzeit 59,333/57,389 s, jeweils exit 0. Keine neue gepaarte Performance-Abnahme und keine Zuordnung der Prefill-Zeitstreuung zu diesem Patch. Die produktive Turn-Auswahl bleibt noch auf dem alten Executor. Diese Entkopplung schließt die gemeinsame Metadaten-Schnittstelle, nicht die Controller-/Cache-/Power- Anbindung; noch kein neues UI-Bundle oder Nachweis der sechs Performance-Zellen. **Power-Steuerung am kanonischen Executor angebunden, 10.09.:** `Execution::load` nimmt jetzt den effektiven `power_percent` entgegen; 0 bedeutet wie im DS4-Executor automatisch 100, Werte über 100 werden vor dem Modellladen abgelehnt. Der reale Chat-Test bezieht den Wert aus `ExecutionPreferences` / `EngineExecutionSettings`; Standard bleibt 100. `DS4_QWEN38_TEST_POWER=75` ist nur ein expliziter Diagnosearm, keine Änderung der Paritätskonfiguration. Die bestehende DS4-Formel ist als `throttle_delay` wiederverwendet: EWMA 0,875/0,125, Pause = Mittelwert * (100-power)/power. Separate persistente Prefill-/Decode-Mittelwerte; keine Pause im Text-Callback. Der AR-Pfad pausiert an seinen Forward-/Lookahead-Grenzen, MTP nach abgeschlossenen Verify-/Repair- bzw. ContextCopy-Runden; Prefill nach ausgeführten Chunks, History-Updates und Tail, einschließlich restaurierter Suffixe. Vor dem Schlafen wird der Modellstream synchronisiert, damit bereits eingereichte GPU-Arbeit nicht durch die Pause läuft. Bei 100 werden weder zusätzliche Uhren gelesen noch Commands eingereicht oder synchronisiert. Keine Chunk-Verkleinerung, keine Kerneländerung. Pausenzähler und tatsächliche Schlafzeit werden in den Chat-Receipts getrennt ausgewiesen; Prefill-Zeit enthält die zusätzliche Warte-/Pausenzeit, Decode-Wallzeit ebenfalls. Der neue kleine Metal-Test lässt ein GPU-Ereignis zunächst uneingereicht: bei 0/100 bleibt es uneingereicht (Commit-Zähler 0, kein Sleep-Aufruf), bei 75 muss es vor Beginn des Sleep-Aufrufs signalisiert sein. Ein Drain-Fehler darf nicht schlafen oder einen erfolgreichen Pausenzähler erhöhen. Ein separater CPU-Test prüft dieselbe DS4-Mittelung und ihren 100%-Bypass. Diese Power-Anbindung liegt weiterhin im `cfg(test)`-Controller, nicht im produktiv ausgewählten QwenExecutor; die gesamte EngineSettings-/MTPLX-Serverdefault-Auswahl und Produktumschaltung bleiben offen. **Power-Verifikation:** Zwei gezielte Power-Tests plus die drei bestehenden AR-/Prefill-Treiberreferenzen bestanden unter Supervisor `2048 15 15`. Test-/Produktions-Clippy mit `-D warnings`, Release-Testbuild, Format und Diffcheck bestanden; Logs `/tmp/ds4-power-{clippy,production-clippy,build}.log`. Testbinary SHA256 `88429c4652219fa1c3db3fd544ee672c80ef2df849631b96560fb0ec4b06380b`. Anschließend vollständige installierte Qwen-Chats, sequenziell AR100, MTP100, AR75, MTP75, unter `81920 30 45` und durchgehendem Canary. Unveränderte `session-chat-20260910.jT3hf5/reference-{ar,mtp}-boundary.stdout.log`-Referenzen, SSD-Ngram, Chunk 2048, Low, Seed 0, gleiche Server-Flags wie im vorherigen Lauf. Alle vier liefen bis EOS und bestanden sämtliche Prompt-/Token-/Text-/State-/ Boundary-/MTP-Cycle- sowie Owner-Abbruch-/Textstop-Assertions. Keine Assertion und keine Referenz geändert. Zähler kumulativ über den Chat einschließlich kurzer Abbruchproben; sie sind nicht mit der Anzahl sichtbarer Tokens gleichzusetzen. | Modus | Supervisor s | Prefill-Pausen | Decode-Pausen | Canary-Proben | Prefill max ms | Decode max ms | | --- | ---: | ---: | ---: | ---: | ---: | ---: | | AR 100 | 56,180 | 0 | 0 | 524 | 3,466 | 0,747 | | MTP 100 | 56,282 | 0 | 0 | 527 | 3,780 | 0,720 | | AR 75 | 90,502 | 7 | 2246 | 846 | 1,515 | 1,393 | | MTP 75 | 90,247 | 15 | 892 | 844 | 2,645 | 1,130 | Überall keine Canary-Fehler/Stalls. Bei 100 tatsächlich 0 s Schlafzeit. Bei 75 AR Prefill/Decode 7,464/22,663 s tatsächliche Schlafzeit, MTP 12,754/20,345 s. Das Duty-Cycle-Setting ist keine Messung elektrischer GPU-Leistung; EWMA und Aufwachlatenz erlauben keine pauschale lineare Laufzeitprognose. Peak Physical AR100/MTP100/AR75/MTP75: 82.720.290.248 / 83.179.927.464 / 82.617.677.328 / 83.078.084.640 Bytes. Rohdaten: `local-eval-results/qwen-power-20260910.K856XD/`, `{throttle,drivers,ar100,mtp100,ar75,mtp75}.{stdout,stderr}.log`. Die 100%-Läufe belegen Funktionsregression und ausgebliebene Drosselung; die 75%-Läufe belegen die aktivierte Steuerung. Kein frisches Referenzpaar, kein Warmup-/Wiederholungsdesign, daher keine neue 2%-Abnahme aus diesen Diagnosezeiten. Kein Bundle, Commit oder Push. **EngineSettings und MTPLX-Serverdefaults im kanonischen Einstieg (10.09.):** `Execution::open(&EngineSettings)` liefert Executor und bestehende `TurnOptions`. Er übernimmt den installierten Modellpfad, integriertes MTP an/aus, Power und den nativen Prefill-Chunk-Override (automatisch 2048). Die gemeinsame `effective_settings`-Aufbereitung liefert nun auch im Drei-Turn-Test Engine- und TurnSettings; die Referenzkonfiguration wird nur noch geprüft, nicht in die Ausführungsoptionen kopiert. Der native Chunk-Vertrag entspricht dem begrenzten Sustained-Pfad mit Final-Logits-Prefill. Die bisherige `Execution::load`-Methode bleibt für unveränderte Modell-/Treiberdiagnosen ohne zusätzliche Serverdefaults. Die Qwen-Verzweigung von MTPLX `_server_runtime_env_overrides` liegt als lokale Override-Map vor: neun Family-Speed-Flags, gemeinsamer Compiled-GDN-Off-Schalter, NAX-Verify-Default 0 und bei MTP zwingender Verify-Snapshot. Keine Env-Mutation, keine TLS-Profilumschaltung. Gewichts-Fusion, CompilePolicy und alle produktiven Graph-Options-Aufrufe des Controllers (auch ContextCopy-Repair) lesen diese Werte. Explizite Operatorwerte bleiben gemäß Referenz erhalten; der zwingende Snapshot ist dieselbe Ausnahme wie im Original. AR-Pipeline/Sync-Eval, native MTP-Tiefe 3, Committed-History, Capture-/Repair-Flags, Cache-Snapshot-/Suffix- und Boundary- Defaults werden in vorhandene Optionsstrukturen übersetzt. Das ist keine Abnahme sämtlicher optionaler MTPLX-Generation-Lanes oder experimenteller Kernel-Overrides. `tools/mtplx-policy-reference.py` ruft ausschließlich die Original-Konfigurations- funktionen aus Commit `e652d55e2652137a4abcf1312357abbf3eb9d692` auf, ohne Modellladen oder Generierung. 268 AR-/MTP-Fälle: unset, explizit ein/aus, leere und ungültige Werte, GDN-Interlock, numerische Grenzen und Boolean-Aliase. Der erste Recorder- Lauf deckte auf, dass Capture-Commit/Deferred-Repair anders als einfache `_env_truthy` mit `env_bool` arbeiten: Aliase enable/disabled akzeptieren, ungültige Werte ablehnen. Rust bildet diese Leser getrennt ab. Der korrigierte Recorder behält Fehlerfälle als solche, statt sie auszuschließen. Alle 268 Vergleiche bestanden. Der Seed der bestehenden eingefrorenen Vollmodellreferenz bleibt explizit 0 im Executor-Test; `GenerationPreferences` akzeptiert aktuell nur positive explizite Seeds. Dieser Fixture-Override ist **kein** Nachweis einer Seed-0-UI-Eingabe. Danach AR/MTP-Vollchats über `Execution::open`, jeweils 100 %, Low, 2K, SSD-Ngram, Supervisor `81920 30 45` und durchgängiger Canary. Anders als zuvor keine manuell gesetzten Qwen-Speed-, Compile-, Sustained- oder Snapshot-Flags: sämtliche 12/13 in `qwen_runtime_setting` protokollierten Umgebungswerte waren `null`; effektive Werte exakt wie die eingefrorene Referenz. Beide Chats einschließlich aller Prompt-/Output-/Logits-/Hidden-/Cache-/Boundary-/MTP-Cycle- und Abbruch-Assertions bestanden. Keine Referenz und keine bestehende Assertion abgeschwächt. AR: 562 Canary-Proben, Prefill/Decode-max 1,416/0,804 ms, Peak Physical 82.725.746.312 Bytes, Supervisor 58,395 s. MTP: 549 Proben, max 2,085/0,559 ms, Peak Physical 83.187.169.336 Bytes, Supervisor 57,055 s. Keine Fehler/Stalls, keine Drosselungspausen. Drei bestehende AR-/Prefill-Treiberreferenzen ohne Servervorgaben bestanden anschließend ebenfalls. Rohdaten: `local-eval-results/qwen-policy-20260910.FBHrg3/`, `{reference,reference-fixed,policy,drivers,ar,mtp}.{stdout,stderr}.log`. Finale Binary SHA256 `2711ff2ae542a91d0c62d69fccc7e62de0deb4a91a884dfd9cb924e03ea559c5`. Test-/Produktions-Clippy, Release-Testbuild, Format und Diffcheck bestanden; Logs `/tmp/ds4-policy-{clippy-final,production-clippy,build-final}.log`. Der Controller ist weiterhin `cfg(test)`; dieser neue Einstieg wird noch nicht vom produktiven Generator ausgewählt. KV-Persistierung, produktive Umschaltung, UI-/Harness-Abnahme und gepaarte sechsstellige Performance-Matrix bleiben offen. Kein Bundle, Commit oder Push; keine 2%-Abnahme aus diesen Diagnosezeiten. **SSD-Checkpoint am kanonischen Live-Owner (10.09., nach dem Policy-Nachweis):** `qwen_mtplx/session_checkpoint.rs` verbindet den vorhandenen Referenz-Codec mit `LiveSession::save_checkpoint/load_checkpoint`. Eine einzelne `QWMTKV01`-Datei enthält rohe Tensorblobs und ein begrenztes Manifest; keine dtype-Konvertierung, keine zweite Datenbank, keine neuen Writer-Threads. Die bestehende DS4-Verwaltung übernimmt weiterhin Conversation-Key, Index, Prefix-Suche, Budget, Touch und Eviction. Temporärdatei, `sync_all` und Rename folgen dem bestehenden Rust-DS4-Verfahren. Modellidentität, Kontext, Vokabular, MTP, Tokenpräfix und vollständige Blobbereiche werden geprüft. Abbruch-/IO-Fehler veröffentlichen weder einen partiellen Checkpoint noch einen neuen Live-Zustand/Tag. Alte `DS4QWN01`-Dateien sind ausdrücklich inkompatibel und müssen vom gemeinsamen Aufrufer als Cache-Miss/Rebuild behandelt werden. Der modellfreie Metal-Test prüft bitgleiches Payload-/Blob-Roundtrip einschließlich BF16, Recurrent-State, MTP und Boundaries, bytegenaue IO-Zähler, fehlende Datei, Abbruch nach IO-Beginn, Modell-/Kontext-/MTP-Wechsel, ungültige Token, überlaufende und falsche Blobbereiche, falsche Tensorgrößen, Trunkierung und altes Dateiformat. Alle Fälle bestanden; ein fehlgeschlagenes Speichern bewahrt die vorherige Datei, fehlgeschlagenes Laden den vorherigen Live-Zustand. Der bestehende vollständige Drei-Turn-Oracle besitzt nun einen optionalen `DS4_QWEN38_CHECKPOINT_DIR`-Diagnosepfad: nach jedem natürlich beendeten Turn Speichern und `KvStore::record`, alle Live-Snapshots und die Engine verwerfen, Engine erneut öffnen, `KvStore` erneut öffnen/find/touch und von SSD laden. Es handelt sich um eine **prozessinterne Engine-Neuöffnung**, noch nicht um einen Neustart des produktiven UI-Prozesses. Die Folge-Turns behalten unverändert sämtliche eingefrorenen Prompt-/Output-/Logits-/Hidden-/Boundary-/MTP-Cycle-Assertions. Kein RAM-Prefix bleibt als alternative Quelle erhalten. Summary → Story → Python bestand AR und MTP bei Power 100, Low, Chunk 2048; keine Drosselungspausen, keine zusätzlichen Voll-Prefills der bereits gecachten History. | Modus | Checkpointgrößen, Turn 0/1/2 (Bytes) | Speichern (ms) | Laden (ms) | GPU-Canary max, gesamt / Prefill / Decode (ms) | | --- | --- | --- | --- | --- | | AR | 675831746 / 714926075 / 723427506 | 359,805 / 519,763 / 438,827 | 181,206 / 217,471 / 185,126 | 6,126 / 1,485 / 0,711 | | MTP | 678764762 / 722567188 / 733621273 | 366,524 / 406,042 / 385,907 | 172,320 / 183,714 / 176,829 | 3,996 / 1,264 / 0,527 | Canary durchgängig inklusive Speichern/Neuladen, 812/727 Proben, jeweils null Fehler/Stalls. Die Gesamtmaxima liegen in Loading; dessen Phasenlabel umfasst hier auch das SSD-Laden. Supervisor-Gesamtzeit 86,094/77,604 s, maximale Physical- Footprints 81.629.560.424 / 82.099.961.736 Bytes. Genau ein Modellprozess, kein Download, Supervisor `81920 30 45`; kein Gesamtlaufzeitlimit. Der kleine Test lief separat mit `2048 15 15`. IO-/Neuladezeiten sind Diagnosewerte mit aktivem Canary und warmem OS-Dateicache, keine SSD-Kaltstart- oder Performance-Paritätsabnahme. Rohdaten: `local-eval-results/qwen-checkpoint-20260910.clSZAD/`, `{small,ar,mtp}.{stdout,stderr}.log`, Testcheckpoints in `{small,ar-cache,mtp-cache}`. Referenzen unverändert: `local-eval-results/session-chat-20260910.jT3hf5/`, `reference-{ar,mtp}-boundary.stdout.log`. Binary SHA256 `8e87e337ac78c502d0d03fccd7f375b61e13ae4cb446c88fad5aa99bcf7feda3`. Test-Clippy und Release-Testbuild bestanden, Logs `/tmp/ds4-checkpoint-{clippy,build}.log`. **Historischer Integrationsblocker (durch den folgenden Anschluss überholt):** `qwen_mtplx` bleibt `cfg(test)`; der produktive Generator wählt noch den alten Executor. Der neue Dateiadapter ist mit dem realen KV-Index im Vollmodelltest geprüft, aber noch nicht mit Bootstrap, Sessionwechsel, Kompaktierung und der produktiven Backend-Umschaltung verbunden. Erst deren Anschluss macht diese Nachweise für UI und produktive Harness wirksam. Keine UI-/Harness- oder 2%-Abnahme, kein Bundle, Commit oder Push. **Produktiver Owner angeschlossen (10.09., nach dem SSD-Checkpoint-Nachweis):** `Generator::open` wählt Qwen jetzt vor dem alten `LoadedModel`-Loader über `Executor::open_qwen` aus. `qwen_mtplx` ist nicht mehr test-exklusiv. Der neue `owner.rs` delegiert vollständige Turns an `LiveSession`, einschließlich AR/MTP, anstatt den alten skalaren Generatorloop zu benutzen. Bootstrap-/Suffix-Prefill, Reset, Resident-Sessionwechsel und Checkpoint-Dispatch erreichen denselben Owner. Die gemeinsame Runtime bleibt der Einstieg von UI und `model-eval`. Der alte Qwen-Executor bleibt für Diagnosepfade vorhanden, wird vom Generator nicht gewählt. `qwen_product_generator_chat_matches_reference` bestand AR und MTP mit den unveränderten drei eingefrorenen Referenzturns: natürliche Abschlüsse, exakte Prompt-/Output-Tokens, Reasoning/Text sowie finale Logits-/Hidden-Hashes. Nach jedem Turn werden Resident-Sessionwechsel und SSD-Restore über den wirklichen Generator geprüft. Zusätzlich bestehen kalter und fortgesetzter Pure-Prefill und dessen Abbruch ohne Veröffentlichung eines partiellen Zustands. Rohdaten: `local-eval-results/qwen-product-20260910.8EeH8M/`, `{ar,mtp}.{stdout,stderr}.log`; Testbinary SHA256 `4cb3f4e0b9e26f441088b8367f7d53a33f6a584a07424cc4ee0e356f44501e7d`. Testzeiten AR 59,52 s / MTP 52,49 s, Canary 555 / 489 Proben, null Fehler/Stalls, Maximum 3,475 / 4,045 ms. Dies sind überwachte Integrationstests, keine gepaarte Performance-Abnahme. Die groben Phasen umfassen auch nachfolgende Checkpointarbeit; ein UI-Render-/Eventloop-Nachweis ist damit nicht erbracht. Der OS-Disk-Write-Zähler enthält ungültige Werte und ist kein Durchsatznachweis. Offen nach diesem Anschluss: tatsächlicher Bootstrap-/Kompaktierungsablauf und Abbruch/Fortsetzung im Generator, normaler Release-Worker mit prozesskaltem Ping, Release-Bundle samt UI-Nachweis sowie die vollständige Performance-Matrix. MTP-Zähler werden bisher am Turn-Ende veröffentlicht, PLE-Hot-Cache-Zähler sind angebunden, weitere SSD-Zähler noch nicht. Die gemeinsame Buffer-Ownership wurde für Produktion aktiviert; Auswirkungen auf DS/GLM müssen mitgemessen werden. Optionale Referenz-APIs und historische Diagnoseadapter sind kein Nachweis, dass alle optionalen MTPLX-Policies produktiv integriert sind. **Lebenszyklus-Nachprüfung, erster Lauf:** Der ergänzte `DS4_QWEN38_TEST_LIFECYCLE=1`-Pfad prüft nach dem Chat den echten `prepare_bootstrap` samt Cache-Hit und `Generator::compact` samt Rebuild. AR bestand die drei Referenzturns erneut, wurde danach im Kompaktierungs-Prefill vom externen 80-GiB-Limit beendet: Physical-Peak 86.164.456.144 Bytes, Lauf 68,460 s, `memory_limit`. Kein erfolgreicher Kompaktierungsnachweis. Bis zum Abbruch lagen Canary-Proben vor; eine finale Canary-Zusammenfassung fehlt wegen des Supervisor-Abbruchs. Rohdaten `ar-lifecycle.{stdout,stderr}.log` im obigen Produktverzeichnis. Wiederholung mit 88 GiB überwachten Speichergrenze, unveränderten Modellparametern und unveränderter Ausführung; kein künstliches Cache-Leeren oder Verkleinern von Prefill-Chunks. Testbinary SHA256 `6c72d5d8ba2ef563a4b5d945d4dc7d0098b16f849be0f126fdc10998eac308d8`. **Lebenszyklus erfolgreich nachgeprüft (10.09.):** Die unveränderte Wiederholung mit 88-GiB-Watchdog bestand AR und MTP einschließlich drei Referenzturns, Bootstrap (37 Tokens), erneutem Bootstrap ohne Prefill und Kompaktierung samt gespeichertem Rebuild. Rebuild 1961 / 2138 Tokens, jeweils `tail_start=2`, nichtleere sinnvolle Task-State-Summary. Supervisor 69,176 / 64,457 s, Physical-Peak 86.300.246.808 / 86.341.305.472 Bytes. Canary 643 / 599 Proben, null Fehler/Stalls, Maximum 3,014 / 3,385 ms. Rohdaten `{ar,mtp}-lifecycle-88g.{stdout,stderr}.log`. Die erhöhte Supervisorgrenze verändert nicht die Engine oder ihre Speicherpolicy; kein Nachweis eines behobenen Leaks. **Normaler Release-Worker, kalter Ping (10.09.):** `--warmup off` ist im `model-eval` verfügbar, Default bleibt `on`; Options-Test bestanden. Normale Binary SHA256 `89d6ef5ea14fbfdb980d4512aee89fbbb77955964f6f52ad8e4c963dd58c9f97`, kein Testbinary-Einstieg. Power 100, Low, Chunk 2048, Kontext 32768, Temperatur 0,6, top-p 0,95, min-p 0, Seed 42, Plain-Chat, maximaler Produkt-Tokenwert, Canary an, 80-GiB-Watchdog, Startup 30 s / Fortschritt 45 s. Keine Downloads, isolierte temporäre Sessions, kein Warmup und kein globales Leeren des OS-Dateicaches. AR/MTP enden natürlich mit „Pong!“, 55 / 63 Completion-Tokens. Gesamt 10,157 / 9,384 s, Laden 6,406 / 5,495 s, gemeldetes Prefillfenster 2,617 / 2,296 s (einschließlich Systembootstrap), Decode 0,953 / 1,409 s. Die 41 Prompttokens enthalten 30 im selben kalten Lauf aufgebaute Bootstrap-Tokens; der Quotient aus 11 Suffix-Tokens und dem gesamten Prefillfenster ist deshalb keine reine Kernel-Prefillgeschwindigkeit. Keine Paritätsabnahme aus kaltem Ping. Canary-Maximum 3,703 / 3,935 ms, im Prefill 0,629 / 0,628 ms; kein Stall. Headless-Control-Loop-Maximum 57 / 47 ms ist keine Messung des GUI-Eventloops. Rohdaten `cold-ping-{ar,mtp}.{stdout,stderr}.log` im Produktverzeichnis. Dabei neu belegt: normale GPU-Busy-/Command-Buffer-Zähler bleiben fälschlich null. Der bisherige Recorder hängt am nativen DS4-Wait, den der kanonische MTPLX-Pfad nicht benutzt. Die separate Canary-Messung ist davon unabhängig. Der Anschluss an MTPLX-Command-Completion ist in Arbeit; keine zusätzlichen GPU-Waits/Flushes als Instrumentationsersatz. Diese Nullwerte sind nicht als GPU-Leerlauf auszuwerten. **GPU-Busy-Instrumentation korrigiert und nachgeprüft (10.09.):** Der vorhandene native Recorder ist nun auch an die asynchrone MTPLX-Command-Completion angeschlossen. Mutexgeschützte Snapshots verhindern konkurrierende Zugriffe von UI/Worker und Completion-Thread; eine Mess-Epoche schließt nach Reset verspätet eintreffende MTPLX-Completions aus dem vorherigen Messfenster aus. Keine neue GPU-Arbeit, kein zusätzlicher Wait, Flush oder geänderter Kernel-/Submission-Plan. Der bestehende Encoder-Regressionscheck prüft nun positive GPU-Zeit und exakt eine Buchung je Command-Buffer auch nach späterem Wait; Canary-Probes bleiben ausgeschlossen. Bestanden unter `test-supervisor 2048 15 15`, `busy-counter.{stdout,stderr}.log`, Testbinary SHA256 `c7cf8b3d524673dad7e1cfeec6de4b7e419129c34f073f042dc377b80234136e`. Erneuter normaler Release-Ping AR/MTP mit unveränderten Parametern, jeweils prozesskalt: natürliches Ende, exakt gleiche Tokenzahlen, Reasoning und Antworten wie vor der Messkorrektur. Binary SHA256 `4763e16687ed53c787825a391f45d51d6fe793f8bb6dc157bf7d4dfd627458ec`. Rohdaten `cold-ping-{ar,mtp}-busy.{stdout,stderr}.log` im Produktverzeichnis. | Messung | AR | MTP | | --- | ---: | ---: | | Gesamter Request inklusive Laden (s) | 8,630 | 8,721 | | Modellladen (s) | 5,505 | 5,494 | | Prefillfenster inklusive Bootstrap (s) | 1,989 | 2,276 | | Decode-Loop (s) | 0,950 | 0,773 | | Completion-Tokens | 55 | 63 | | Decode-Loop tok/s | 57,90 | 81,54 | | GPU-Zeit, Summe der Command-Buffer (ms) | 2121,73 | 1980,39 | | Längster Command-Buffer (ms) | 112,22 | 120,46 | | Command-Buffer | 12730 | 9162 | | GPU-Canary max, gesamt / Prefill (ms) | 3,444 / 0,616 | 3,873 / 0,620 | | Headless-Control-Loop max (ms) | 52 | 59 | Canary 82 / 84 Proben, null Fehler/Stalls, Supervisor Exit 0. Summierte GPU-Zeit ist keine queueübergreifende Vereinigungszeit. Unterschiedliche Pipeline-/OS- Caches zwischen Prozessstarts verhindern eine Performance-Aussage aus dem Vorher/Nachher-Ping; insbesondere die schnellere MTP-Wiederholung ist **kein** belegter Beschleunigungseffekt der Messkorrektur. CPU-Overhead der Completion- Instrumentation bleibt Teil der noch offenen warmen Referenzabnahme. Normaler Headless-Einstieg ist jetzt geprüft, ein neues GUI-Bundle und GUI-Eventloop-Nachweis bleiben offen. Keine Behauptung der vollständigen 2%-Parität. **Laufende MTP-Zähler und Abbruch/Fortsetzung nachgewiesen (10.09.):** Der kanonische `decode_mtp` meldet über den vorhandenen `TurnProgress`-Kanal jeden abgeschlossenen Zyklus. Der produktive Owner veröffentlicht diese Werte sofort in denselben atomaren `Metrics`, die UI und Harness lesen. Keine neue GPU-Arbeit, kein zusätzlicher Thread und keine zusätzliche Synchronisation. Der bisherige Turn-Ende-Sammelpass entfällt, damit keine doppelte Buchung entsteht. Verifier- und Repair-Zeiten bleiben bis zur Umrechnung kumulativ innerhalb des Turns; Sub-Millisekunden-Anteile werden nicht je Zyklus abgeschnitten. Bei Abbruch bleibt der letzte beobachtete abgeschlossene Zyklus erhalten; unvollständige Zyklen werden nicht als abgeschlossen behauptet. Zusätzliche Zählkorrektur: Context-Copy-Runden führen ebenfalls einen gebatchten Target-Verifier aus. Vorher wurden sie bei `verifier_passes` ausgelassen. Der eingefrorene MTP-Chat enthält pro Turn 148+7, 640+2 und 93+2 MTP-/Context-Copy-Verifikationen. Native MTP-Draft-/Acceptance-Zähler zählen weiter nur die nativen Drafts, nicht die kopierten Kontexttokens. Der modellfreie Test prüft Live-Publikation ohne Turn-Ende, Zeit-Rundung, Context-Copy-Verify, Primary-EOS ohne Verify und ausbleibende Doppelbuchung beim Finalize; bestanden. Der vollständige Produkt-Generator-Test prüft jetzt zusätzlich, dass MTP-Zähler bereits während der Textausgabe eintreffen, und vergleicht nach jedem Turn deren Delta mit allen eingefrorenen Referenz-Cycles. AR muss die MTP-Zähler unverändert lassen. Beide Modi bestehen weiterhin exakte Tokens, Texte, Logits-/Hidden-Hashes, Resident-Switch und SSD-Restore. Im erweiterten Lebenszyklustest wird auf einem kopierten Checkpoint ein ununterbrochener Kontrollturn erzeugt. Abbruch vor Decode und während Decode müssen die Originaldatei SHA256-identisch erhalten. Nach Aufhebung des Abbruchs muss derselbe Request dieselben finalen Tokens, Reasoning und Text wie der Kontrollturn liefern. AR und MTP bestanden jeweils mit 23 Completion-Tokens und „PONG“. Abgeschlossene MTP-Zähler bleiben auch nach Abbruch sichtbar. Bootstrap- Cache-Hit und Kompaktierung/Rebuild bestehen anschließend ebenfalls. Dies testet den produktiven Generator, nicht UI-Buttonzustände oder jeden denkbaren IO-Abbruch. Rohdaten: `local-eval-results/qwen-live-metrics-20260910.iD9AZm/`, `{unit,ar,mtp}.{stdout,stderr}.log`, isolierte Checkpoints in `{ar,mtp}-cache`. Testbinary SHA256 `d9c6fd174b51af793b61d0f06740cdc398fa85778fb8ec8d908ec442cbefa75b`. Power 100, Low, Referenz-Seed 0, Chunk 2048, Kontext 32768; nur installierte Gewichte. Volltests `test-supervisor 90112 30 45`, kleiner Test `2048 15 15`. AR/MTP Supervisor 72,130 / 70,118 s; Physical-Peak 86.596.617.488 / 86.535.603.592 Bytes. Canary 672 / 651 Proben, keine Fehler/Stalls, Maximum 3,004 / 3,192 ms, im Prefill 0,887 / 0,998 ms. Keine warmen gepaarten Performance-Abnahmen aus diesen Integrationsläufen. Clippy-Log `/tmp/ds4-live-mtp-clippy3.log`, Build `/tmp/ds4-live-mtp-test-build.log`. Die normale Harness serialisiert die kumulativen `speculation`-Felder nun auch in `runtime_sample`, nicht nur als Turn-Delta im Endergebnis. Ein normaler Release-Lauf zur Nachprüfung dieses JSON-Einstiegs ist wie folgt bestanden. **Warmer laufender Chat über die normale Headless-Binary (10.09.):** `warm-chat-mtp.{stdout,stderr}.log` im selben Verzeichnis, normale Binary SHA256 `b74e3126e911b3f57d83829ee216c77d45fbe29fb597694ab28c2895ec1301dc`. `model-eval --warmup on --plain-chat on`, README-Summary → Lighthouse-Story → Python `is_prime` mit fünf Assertions, ein zusammenhängender Chat. Power 100, Low, Chunk 2048, Kontext 32768, Temperatur 0,6 / top-p 0,95 / min-p 0, Seed 42, MTP an, Canary an, Speicherwatchdog 88 GiB, Startup 30 s / Fortschritt 45 s. Keine Gesamtzeitbegrenzung; alle drei Messturns enden natürlich mit `stop`. README SHA256 `80c01ea096843312de6662d3cd8c94c8e14bdf286b58824752981fc4920fd1f8`. Der vollständige erste Prompt ist nach direktem JSON-Vergleich bytegleich mit `reference-mtp-boundary.stdout.log`; die frühere Annahme eines abweichenden README-Inhalts ist damit verworfen. Referenz-Seed 0 und erster Referenz-Prefill ohne Bootstrap-Reuse unterscheiden sich von diesem Lauf: weiterhin keine gepaarte Performance-Abnahme, keine Verrechnung als 2%-Pass. | Messturn | Prompt / cached / completion | Gesamter Turn (s) | Prefillfenster tok/s | Decode-Loop tok/s | | --- | --- | ---: | ---: | ---: | | Summary | 2748 / 30 / 519 | 9,446 | 1304,22 | 72,14 | | Story | 3296 / 3268 / 1450 | 28,113 | 264,15 | 52,13 | | Python | 4780 / 4747 / 230 | 3,151 | 242,65 | 81,00 | Während Decode enthält die Harness 7 / 27 / 3 `runtime_sample`-Ereignisse mit steigenden kumulativen Cycle-Zählern 36→185 / 208→841 / 868→913, nicht erst ein Endergebnis. Summary fachlich lesbar, abgeschlossene Lighthouse-Geschichte ohne Rückfrage, Python-Code vor Ausführung geprüft. Die generierten fünf Asserts und ein unabhängiger Trial-Division-Vergleich für -10 bis 5000 (5011 Fälle) bestehen unter isoliertem Python mit 3-s-CPU-Grenze; keine Imports im generierten Code, keine Netzwerk-/Toolnutzung. Beleg `python-validation.stdout.log`. Gesamtprozess einschließlich Warmup 49,581 s, Supervisor Exit 0, maximaler Fortschrittsabstand 1,625 s. Canary 456 Proben, null Fehler/Stalls, Maximum 3,293 ms; Headless-Control-Loop-Maxima 53 / 37 / 33 ms. Der Supervisor meldet 82.983.156.272 Bytes als abgetasteten Peak-Footprint; dieser ist kein lückenloser Kernel-Lifetime-Peak. GPU-Busy-Zähler sind in allen Turns positiv. Clippy und Formatprüfung bestehen (`/tmp/ds4-live-mtp-final-clippy.log`). Kein GUI-Bundle, kein GUI-Eventloop-Nachweis und keine vollständige Referenzmatrix in diesem Schritt. **Warmer Bootstrap-Suffix: Vergleichsprofil und Boundary-Lücke (10.09.):** Die ersten Vergleichspaare unten sind **Zwischendiagnosen, keine Freigaben**. Die strengere Zustandsprüfung deckte danach einen nicht angeglichenen Sustained- Prefill-Modus auf. Maßgeblich ist die abschließende Profilkorrektur unten. Der angeglichene Referenztreiber `tools/mtplx-execution-reference.py --source-run` übernimmt den vollständigen normalen Harness-Startvertrag einschließlich Warmup, Seed 42, Sampler-Floatwerten und Bootstrap-Reuse. Er akzeptiert nur drei natürlich abgeschlossene Plain-Chat-Turns und prüft je Turn Prompt-, Cache- und Ausgabetokenzahl sowie den vollständigen Text. Der erste Versuch gegen den oben genannten alten Stand scheiterte ausdrücklich: Summary 448 statt 519 Tokens. Rohdaten: `local-eval-results/qwen-matched-warm-20260910.ig0qT1/`. Erste Untersuchung: MTPLX `_prefill_restored_prompt_suffix` übergibt die Chunkgröße **implizit**. Ohne `MTPLX_SUSTAINED_PREFILL` ist zunächst der gesamte Body ein Span, den die aktive rekurrente Boundary-Policy auf ihr 256er-Tailraster aufteilt. Der kalte committed-MTP-Pfad dagegen übergibt 2048 explizit. Rust hatte im warmen Pfad eine eigene gleichmäßige 2048er-Schleife und erfasste dort keine Boundaries. Der erste Patch verwendete den vorhandenen `prefill::spans`-Helper mit denselben Regeln und erfasst absolute rekurrente Zwischenzustände vor dem History-Append. Optionale Capture-Fehler brechen wie im Original den Turn nicht ab. Keine pauschale Änderung des UI-Chunkwerts und keine neue Cache-Persistenz. Der neue normale MTP-Chat und der anschließende unveränderte MTPLX-Lauf stimmen für **alle drei Turns** in Prompt-/Cache-/Ausgabetokenzahlen und vollständigem Text überein: 2748/30/448, 3225/3197/997, 4256/4223/301. Beide enden natürlich. Summary-Prefill-Fortschritt nun in beiden Pfaden: 30, 286, 542, 798, 1054, 1310, 1566, 1822, 2078, 2334, 2590, 2747, 2748. Damit ist die neue Warm-Prefill-Lücke nicht bloß durch ein anderes gesampeltes Ergebnis verdeckt. Rohdaten: `local-eval-results/qwen-warm-suffix-20260910.vWPeE5/`, `product-mtp-metal.{stdout,stderr}.log` und `reference-mtp.{stdout,stderr}.log`. Binary SHA256 `bff5b55c15a101f236f6bf3466d62154417ef9a93ee235b7efbae6ee570eddd9`. MTP-Produkt: 401 Canary-Proben, null Fehler/Stalls, Maximum 3,158 ms, Headless-Control-Loop-Maxima 38/32/44 ms. Prozess inklusive Warmup 43,565 s, abgetasteter Peak-Footprint 80.643.439.968 Bytes. Referenz-Supervisor Exit 0, 44,238 s und Lifetime-Peak 81.251.187.272 Bytes. Sein Disk-Write-Rohzähler läuft erneut über und ist kein brauchbarer IO-Nachweis. Boundary-Regressionstest und Referenztreiber-Vertragstest bestehen, Release-Build und fokussiertes Release-Clippy bestehen. Ein erster Sandbox-Versuch endete vor der Inferenz mit fehlendem Metal-Gerät; der oben ausgewertete Lauf erfolgte mit Metal-Zugriff. AR-Vergleich und exakte finale Tensor-/Tokenprüfung des warmen Produkt-Generators folgen. Canary aktiv, Einzelpaare und teils parallele CPU-Kompilierung: ausdrücklich **keine saubere 2%-Performance-Abnahme**. **Strengerer Nachweis und abschließende Profilkorrektur:** Der vorhandene Produkt-Generator-Test unterstützt nun Bootstrap/Warmup vor dem laufenden Chat und prüft neben exakten Tokens, Texten und finalen Logits-/Hidden-Hashes auch rekurrente Boundary-Positionen. Der erste MTP-Turn scheiterte (`exact-mtp.*`): Rust bewahrte Bootstrap-Boundary 29, die Referenz nicht. Ohne Sustained-Modus wählt MTPLX für den kalten MTP-Bootstrap `_prefill_with_hidden_sequence` ohne Boundary-Capture; die UI nutzt hingegen den begrenzten Streaming-Pfad. Der vorhandene `mtplx-policy-reference.py` bildet diese native Policy bereits mit `MTPLX_SUSTAINED_PREFILL=1` ab. Dies fehlte im neuen Chat-Referenztreiber. Der Treiber setzt jetzt denselben Sustained-Modus und den originalen request-lokalen Chunk-Override. Rusts warmer Pfad verwendet entsprechend den vorhandenen Spans-Helper mit 2048er-Hauptchunks und 256er-Unterteilung nur im letzten Body-Chunk. Die zwischenzeitliche Unterteilung des gesamten Bodys nach dem nicht angeglichenen Referenzprofil ist zurückgenommen. Die echte Korrektur sind das fehlende Tail-Raster und absolute Captures vor dem History-Append, nicht eine allgemeine Chunkverkleinerung. Optionales Capture bleibt wie im Original fehlertolerant. End-to-end-Nachweise dieses endgültigen Profils stehen zum Zeitpunkt dieses Eintrags aus; obige Text-Pässe ersetzen sie nicht. Zusätzlich korrigiert: Der erste AR-Referenzlauf verlor den Bootstrap-Hit, weil der Treiber `hidden_variant=None` statt der vom originalen Resolver normalisierten Identität `post_norm` bankte. Nach Korrektur passen auch dort die Texte aller drei Turns (`reference-ar-policy.*`), jedoch noch unter dem zwischenzeitlichen Nicht-Sustained-Profil. Das war kein Produktfehler. **Endgültiges Sustained-Profil in beiden Modi bestanden (10.09.):** `local-eval-results/qwen-warm-suffix-20260910.vWPeE5/manifest.md` trennt alle Zwischenstände von den maßgeblichen `*-sustained.*`-Receipts. Die normalen UI-Runtime/Headless-Chats und originalen MTPLX-Chats stimmen in allen drei Turns überein: AR 570/1129/266, MTP 438/1144/279 Ausgabetokens. Der erweiterte Produkt-Generator-Test besteht für beide Modi außerdem exakte Tokens inklusive EOS, finale Logits-/Hidden-Hashes, rekurrente Grenzen, laufende MTP-Zähler, Resident-Wechsel und SSD-Restore. Die separate Lifecycle-Cancel-Erweiterung wurde in diesen Wiederholungen nicht zugeschaltet. Python-Ausgaben bestehen je fünf Assertions und 5011 unabhängige Fälle. Die fehlgeschlagenen strengeren Tests bleiben erhalten; keine Abschwächung der Assertions für den grünen Stand. Normale AR/MTP-Canary-Maxima 3,741/3,471 ms, null Fehler/Stalls; kein tatsächlicher GUI-Eventloop-Nachweis. Release-Binary SHA256 `0ecc5f13e94a78f71c116d877ab0fa0101edf76e2b9b4cfdecc40c927d7e1b90`. Fokussierte Tests, Clippy und Formatcheck bestanden. Die auffällig langsame AR-Referenz in diesem Einzelpaar wird nicht als bewiesener Produktvorteil gewertet: saubere alternierende Wiederholungen ohne Canary stehen aus. GLM-2-Row-Verify, vollständige sechszellige Performance-Abnahme und aktualisiertes GUI-Bundle bleiben offen. Die Warm-Prefill-Funktionslücke ist damit geschlossen, nicht das gesamte Paritätsziel. **Drei alternierende Paare pro Qwen-Modus ohne Canary — keine Abnahme (10.09.):** `local-eval-results/qwen-clean-pairs-20260910.Y2DWsl/{manifest.md,comparison.json}` enthält zwölf natürlich abgeschlossene Prozesse mit identischen Antworten und vollständigen Settings-/Rohdatenbelegen. Reihenfolge pro Modus P1,R1,R2,P2,P3,R3; Power100, Low, gleiche Warmup-/Bootstrap-/Sustained-Verträge, kein Build parallel. Die Referenz kann mit `--token-events progress` die Token-JSON-Ausgabe auf echten Fortschritt einmal pro Sekunde begrenzen; Tokens/Text bleiben vollständig in den End-Receipts. Kleiner modellfreier Test prüft die Rate und verhindert Fortschritt ohne neue Tokens. Beide Canary-Summaries bestätigen jeweils null Proben. Der frühere günstige Einzelvergleich ist keine ausreichende Freigabe: Im zweiten Paar liegt Rust AR bei Summary/Story/Python 2,34/4,63/10,71% hinter MTPLX, MTP 6,48/4,26/3,24%. Im ersten und dritten Paar ist Rust schneller; beide Programme driften im Verlauf stark. Kein Aussortieren langsamer Läufe oder Median-Pass. MTP-Story behält 515 Cycles / 1539 Drafts / 624 Accepts, doch GPU-Busy steigt 17,193→21,100s und CB-Zahl 142256→147830; Checkpoint-Write bleibt 358→366ms. Das verengt die Suche, beweist aber weder thermisches Drosseln noch einen Rust-Schedulerfehler. Die GPU-Clock-/Temperaturzeitreihe fehlt. Passive Diagnose: macOS meldete keine Thermalwarnung und normalen Speicherdruck. Powermetrics ist ohne Administratorpasswort nicht verfügbar. Das installierte mactop lieferte zwei Idle-Samples, beendete sich aber mit Exit139; dieser Hilfsprozess ist kein verlässlicher Zusatzmonitor und wurde nicht in die Benchmarkserie eingebaut. Die Rust-Speicher-/Fortschrittswächter blieben aktiv. Nächster Messblock: zuverlässige optionale passive Geräte-Telemetrie und Submission-/GPU-Zeitkorrelation; Prefill-Zeitgrenzen getrennt angleichen. Keine Behauptung, das gesamte Ziel sei nur durch Messrauschen verfehlt: Ursache bleibt zu belegen, GLM-2-Row-Verify und DS/GLM-Abnahme bleiben offen. **Prompt-Eval-Messgrenzen im gemeinsamen Produktpfad veröffentlicht (10.09.):** `local-eval-results/qwen-prompt-timing-20260910.gPvUlU/{manifest.md,comparison.json}` belegt vier vollständige serielle Chats (Produkt/MTPLX, AR/MTP). Die bereits berechneten Target-/History-/Restore-Zeiten werden vor Decode über dieselben MetricsSnapshots veröffentlicht, die UI und Harness beobachten. Das bisherige UI-Prefillfenster bleibt unverändert; nicht verfügbare Messung bleibt `null`, gemessener Exact-Hit darf null Sekunden haben. Keine neue GPU-Arbeit oder Änderung der Ausführungsstrategie. Regressionstest prüft Reset und dass spätere Checkpoint-/Decode-Arbeit die Promptzeiten nicht verändert. Alle Antworten/Tokenzahlen stimmen mit Original und vorheriger Clean-Serie überein. Die neue Sicht grenzt einen verbleibenden MTP-Summary-Rückstand ein: Eval Rust 2,999957s / MTPLX 2,887888s, also -3,736% Durchsatz; History 52,902 / 52,791ms, Target 2,947055 / 2,835097s. In diesem Paar liegt der Rest im Target-Intervall, nicht im History-Aufbau oder Checkpoint. Ursache innerhalb Target (GPU-Takt/Dispatch/Streaming/Kernel) weiter offen. Andere Turns in diesem Einzelpaar schneller, aber keine Aufhebung der vorherigen Drift und kein 2%-Pass. Originale Prompt-State-Gesamtzeit und UI-Phase bleiben wegen zusätzlicher Arbeit ausdrücklich getrennt. Alle Wächter beendet ohne Fehler; Canary aus, kein GUI-Eventloop-Nachweis. Fokussierter Regressionstest, Treibertests, Release-Clippy, Build, Format- und Diffcheck bestanden. P14–P16 und Bundle weiter offen. **Restumfang (historisch; nachfolgende Produktnachweise oben beachten):** Nicht-streamender Hidden-Sequence-Prefill und Session-Restore, optionale Prefill-Cleanup-/Repaging- und recurrent Boundary-Snapshot-Pfade mit dem AR-Decode verbinden, Default-GPU-RNG in den Owner integrieren, verbleibende MTP-Options-/Requestpfade und die Guard-/Drain-Übergänge einschließlich Owner-Progress sowie die produktive UI/Harness-Integration abschließen. Die sechs vollständigen Geschwindigkeitsvergleiche sind noch abzuschließen. Diese Modulnachweise sind kein Nachweis der vollständigen spekulativen Generierung oder der Performance-Parität aller drei Modelle. **Realer MTP-Head mit Draft/Verify/Commit, 2026-09-10:** Der persistente `Execution`-Pfad besitzt zusätzlich den MTP-QSA-Cache und verwendet die bestehenden `TextModel::mtp_forward`-/`mtp_update_cache`-Graphen über `draft` und `append_mtp_history`. Trunk-Aufrufe geben den bereits modellseitig gehaltenen Widened-Stream weiter; Float32-Diagnose nutzt denselben Auswerter für Logits und Hidden States. Keine neuen Kernel oder Engine-Duplikate. Der Vollmodell-Oracle `tools/mtplx-execution-reference.py --mtp` lädt den installierten Head über das originale `Model.attach_mtp`. Er prüft eine zusammenhängende echte Modelloperationsfolge, **nicht** den vollständigen `generate_mtpk`-Sampler/Generator: - Kalter Ping: Promptkörper (40 Tokens) und letztes Token getrennt, entsprechend `generation._prefill_with_hidden_sequence`; 40 verschobene Hidden/Token-Paare für den Draft-Cache. Kein ungeteiltes 41-Token-MTP-Prefill. - Drei rekursive Draft-Aufrufe mit dem tatsächlich geladenen Head, anschließend Vier-Token-Verify mit originalem Capture-Scope und GDN-/PLE-Snapshots. - Tatsächliche Greedy-Ablehnung nach dem ersten akzeptierten Draft: zwei von vier Verify-Eingaben bleiben. Originaler `commit_verified_window`, MTP-Trim von Offset 43 auf **41**, Erhalt der ersten autoritativen Draft-Zeile, Ergänzung nur der folgenden Target-Historie bis Offset 42. Dies entspricht dem Retain-/Reappend-Pfad in `generation.generate_mtpk` um Zeile 12110. - Nächster Target-Aufruf und nächster Draft bei Offset 43 prüfen die Wirkung des Commits auf die Fortsetzung, nicht nur die Rückgabewerte des Trim-Aufrufs. Referenz und Rust stimmen für alle 40 Prefill-Logit-Reihen sowie **16 vollständige Logit-/Hidden-State-Fingerprints**, Shapes, Greedy-Entscheidungen und Cache-Offsets bitgenau überein. Zwei separat geprüfte Konfigurationen: direkte Modell-Defaults und originale MTP-Server-Familiendefaults (13 protokollierte Werte, einschließlich `MTPLX_SKIP_VERIFY_SNAPSHOT=0`). Das Rust-Testprogramm prüft diese Umgebungswerte vor dem Laden, ebenso Vollständigkeit und Reihenfolge der Referenzoperationen. Rohdaten im bestehenden `execution-20260910.Ngpzu7/`: `reference-mtp-retained.*` / `canonical-mtp.*` (Familiendefaults), `reference-mtp-plain.*` / `canonical-mtp-plain.*` (direkte Defaults). Das frühere `reference-mtp.*` ist durch den Retain-Abgleich ersetzt: es baute die erste bereits autoritative Draft-Zeile unnötig neu auf und ist **keine** Abnahmegrundlage. Sein Disk-Write-Rohzähler enthält zudem einen offensichtlich ungültigen OS-Wert nahe u64::MAX; daraus werden keine IO-Leistungswerte abgeleitet. Alle vier maßgeblichen Prozesse einzeln unter unverändertem `test-supervisor 81920 30 45` und durchgehendem 100-ms-GPU-Canary mit 2-s-Abbruch. Keine Canary-Fehler, alle Prozesse regulär beendet. Lifetime-Peak MTPLX/Rust: 76.770.450.672 / 76.379.298.192 Bytes (Familie), 74.458.239.088 / 74.179.498.048 Bytes (direkt). Canary-Maxima MTPLX/Rust **4,170 / 15,104 ms** (Familie) und **3,911 / 92,204 ms** (direkt). Beide Rust-Ausreißer liegen im Laden, nahezu vollständig bis zur Scheduling-Rückmeldung. Der Host-gemessene Wait-Wert trennt hier GPU-Scheduling und verspätete Probe-Thread-Rückkehr nicht; die Latenzdifferenz bleibt offen, wird nicht durch das 2-s-Risikoflag wegdefiniert. Release-Testbuild, gezieltes warnings-denied Clippy und Format-/Diffprüfung bestanden. Keine Downloads, kein Bundle, Commit oder Push. **Weiter offen:** vollständiger Sampler/Generator einschließlich RNG, adaptiver Draft-Tiefe, natürlichem MTP-EOS und laufendem Chat; produktiver Executor; Serverprofil-/Lazy-Eval-/Submission-Vertrag. Die bisherige Bank erzeugt MTP- Ladedeskriptoren noch vor der Trunk-Materialisierung (Head-Daten bleiben lazy), während MTPLX den Head erst danach anhängt; auch diese Reihenfolge ist vor Produktabnahme anzugleichen. Der neue Pfad bleibt `cfg(test)`. Die 2%-Matrix und UI-/Headless-Responsiveness-Abnahme sind damit ausdrücklich nicht erreicht. Modellweiter Capture-Commit prüft zunächst alle Einträge. Erst danach erfolgen QSA-Trim, reine GDN-Rekurrenz über das akzeptierte Präfix beziehungsweise PLE-Snapshot-Restore, erneutes Staging und Layer-Forward des Präfixes. Ablehnungen bleiben ohne Cache-Mutation; Capture-Clear entfernt nur Capture- Referenzen. Keine zusätzlichen Eval-/Wait-Grenzen im Commit eingeführt. Prüfbelege: vorhandene Decoder-Fixtures um den echten äußeren Modellaufruf erweitert, beide Attention-Typen mit/ohne PLE, cache-only Prefill, Head-Slicing, Capture an/aus und Trace-Wiederverwendung. Bekannte Embedding-/Widened-/Logits- Werte bitgenau, fehlender Snapshot unverändert abgelehnt, Zwei-Token-Commit erfolgreich; PLE-History ist danach `[3,4]` statt Verify-Tail `[5,6]`. Fortsetzung mit übergebenen Embeddings und separatem Head ebenfalls bestanden. Zusätzlicher CPU-Test prüft Compile-Kill-Switch und Run-Grenzen. Rohdaten: `local-eval-results/model-graph-20260909.JbRO3E/commit.*.log`; GPU unter unverändertem `test-supervisor 2048 15 15`, kein Modell geladen. Release-Testbuild, warnings-denied Clippy, Quell-Identität und Format-/Diffprüfung bestanden. Die synthetischen Ein-Layer-Smokes sind keine vollständigen Golden-Master-Modellfixtures oder Durchsatzmessungen. P16 und die Sechs-Zellen- Performance-Abnahme innerhalb 2 % bleiben offen. **MTP-Head-Verbindung 2026-09-09:** `qwen_mtplx/mtp.rs` und die Methoden `mtp_forward`, `mtp_update_cache`, `make_mtp_cache` am äußeren Modell bilden `qwen4_exp.py:4134–4250` ab. RMSNorm über die volle Breite 10240 vor dem Reshape in vier 2560-Streams, gemeinsame Hidden-Projektion, normierte und projizierte Token-Embeddings als Broadcast-Add, eigener nicht-PLE-QSA-Decoder und eigener Mixer. Der LM-Head und das Embedding bleiben mit dem Trunk geteilt. Rekursive Drafts verwenden den Pre-Mixer-Output des vorherigen Drafts; Cache-only Updates erzeugen weder Mixer noch LM-Head. Übergebene Embeddings ersetzen den Lookup, Positionen kommen aus dem eigenen QSA-Cache. Der verbundene synthetische Test prüft drei rekursive Drafts und danach mehrzeilige Cache-Updates (2 Lookup-Zeilen und 3 explizite Embedding-Zeilen), bekannte BF16-Ergebnisse mit unterschiedlichen Hidden-Streams, Offset-Fortschritt, optionale Hidden-Ausgabe und unveränderte Trunk-Caches/`last_widened`. Der erste Lauf (`head.*.log`) scheiterte beim mehrzeiligen Update am zuvor fehlenden batched QuantizedMatmul-Zweig. Dieser wird nun direkt nach `quantized.cpp` ausgeführt: originale Batch-Strides, `_batch_1`-Kernel aus der unveränderten gepinnten Metallib und kein Split-K bei B > 1. Kein Zerlegen in Einzelzeilen oder zusätzliches Contiguous-Materialisieren als Ersatz. Nach Ergänzung bestehen beide Decoder-Tests (`fixed.*.log`, 0,33 s, gesampelter Peak-Footprint 314.868.528 Bytes). Der bestehende affine Referenztest besteht unverändert 78 Fälle in je drei physischen Varianten, also 234 exakte Vergleiche (`affine.*.log`, 1,00 s). Der zusätzliche Batch-Test besteht 24 Identitätsprojektionen mit K=64/128/2560, M=1/3/33/64 und Broadcast- beziehungsweise permutierten Batch-Strides. Er prüft bitgenaue Ausgabe und die tatsächlich ausgeführten Kernel samt Geometrie. 21 Fälle dispatchen ohne Inputkopie direkt batched; bei drei Broadcast-Fällen mit M=1 verlangt bereits die Referenz wegen des Null-Strides der Singleton- Matrixachse eine Kopie und anschließend non-batched Dispatch. Die anfangs pauschale Ein-Dispatch-Erwartung wurde entsprechend korrigiert, nicht der Referenzpfad verändert (`batched-fixed.*.log`, 0,25 s, gesampelter Peak 163.578.600 Bytes). Release-Testbuild, warnings-denied Clippy für App/Tests, beide CPU-Policy-Tests, Quell-Identität sowie Format-/Diffprüfung bestanden. Rohdaten: `local-eval-results/mtp-head-20260909.gXSh00/`. Alle GPU-Läufe einzeln unter `test-supervisor 2048 15 15`, keine Modelle geladen oder heruntergeladen. Dies ist ein Funktionsnachweis mit künstlichen Gewichten, kein Nachweis der realen MTP-Akzeptanz, Compile-Fusion oder Performance-Parität; der gesamte kanonische Pfad bleibt `cfg(test)`. **Arraygraph-Nachweis 2026-09-09:** `qwen_mtplx/moe.rs` bildet die tatsächliche Aufruffolge von MTPLX `SparseMoeBlock`, `_FusedGateUpSwitchGLU` und dem gepinnten `SwitchGLU`/`Qwen3NextMLP` ab: - Präziser Softmax über alle Experten, ArgPartition, strided Top-k-Slice, GatherAxis und optionale Score-Normalisierung bleiben einzelne Array-Knoten. - Gather-Sort ab 64 Routen, Argsort/inverse Argsort, U32-Floor-Divide, Gather/Unsort und die ursprünglichen Expand-/Squeeze-/Reshape-Views. Expert- und Shared-Gewichte bleiben graph-eigene Arrays. - Gemeinsame Gate/Up-Projektion verwendet Split, den vorhandenen kompilierten SiLU und gewöhnliche Multiplikation. Getrennte Projektionen verwenden den unveränderten kompilierten SwiGLU-Kernel als **einen** Knoten. Experten: Up vor Gate; Shared Expert: Gate vor Up, wie in den beiden Referenzklassen. - Fusioniertes AR (S=1) und Verify (S=2–4) haben zwei CustomKernel-Knoten mit Original-Inputreihenfolge, Output-Layouts, Gruppen32/64 und Dispatch-Geometrie. Sie werden nur bei den ursprünglichen Flag-/Batch-/Quantisierungsbedingungen selektiert. Der Shared-Gate-Aufruf liegt im fusionierten Zweig vor dem Shared MLP, im Standardzweig danach. Keine zusätzliche Eval-/Wait-Grenze im Modellblock. `mtplx_graph_sparse_moe_matches_reference` vergleicht die unveränderten 220 vollständigen MTPLX-MoE-Belege zweimal: zunächst mit lazy Parameter-Views, danach mit zuvor ausgewerteten Parametern. Eingabe und Modellbesitzer werden vor der Auswertung freigegeben; der Graph muss ihre Lebensdauer selbst halten. **440/440 Ausgaben exakt**. Rohdaten: `local-eval-results/moe-graph-20260909.xLwfFW/graph.*.log`. Diagnostischer Gesamtlauf 17,988 s, OS-Lifetime-Peak 5.194.256.488 Bytes (4,84 GiB), unter dem unveränderten 8-GiB-/15-s-Wächter. Dies ist kein Modell-Durchsatzbenchmark und kein Vergleich gegen die frühere Buffer-Testzeit. Der zusätzliche vorhandene GatherQMM-Test einschließlich Streamwechsel, physischer Views und lazy/vorbereiteter Ausführung ist ebenfalls bestanden (`gather.*.log`). Der anschließende vollständige Lauf mit Dispatch-Erfassung (`dispatch.*.log`) besteht ebenfalls alle 440 Vergleiche. Zusätzlich wird an der tatsächlichen nativen Dispatch-Grenze geprüft: exakt die beiden passenden fusionierten Kernel in H-/Down-Reihenfolge, Gruppen-/M-Spezialisierungen, Grid und Threadgroup sowie `dispatchThreads`; in allen nicht geeigneten Fällen keine dieser beiden Fusionen. Quell-Identitätsprüfung, Release-Testbuild, warnings-denied Clippy und Format-/Diffprüfung sind bestanden. Der gemeinsame synthetische Pack-Generator berechnet nun `n*k/32*bits`, damit die gültigen 512-Experten-Packs nicht bereits im Zwischenprodukt `n*k*bits` einen u32-Überlauf erzeugen; die Pack-Werte bleiben identisch. - MTPLX `_FusedGateUpSwitchGLU.__call__` sortiert ab 64 Routen und benutzt den gemeinsamen gate/up-Gather auch im sortierten Fall. Der vorangestellte Kommentar zur Large-M-Fallback-Absicht ist nicht der ausgeführte Code. Shared Expert ist ebenfalls gemeinsam gepackt. Der noch nicht migrierte Rust-Produktpfad führt beide Prefill-Projektionen getrennt aus; der neue Arraygraph ist oben belegt. - Aktivierte gepackte Gewichte, Top-10-Routenauswahl/Ties, Sortiergrenze S=5/6/7, inverse Permutation, Gewichtung, Tile-Reste und stark ungleich verteilte Experten vergleichen. Auch der standardmäßig deaktivierte `FUSED_MOE_VERIFY` gehört gemäß Auftragspräzisierung zum Port, ohne ihn abweichend zur Referenz zu aktivieren. - Abnahme: Referenz-Outputs und Routenzuordnung für identische Matrizen; bestehender `qwen_sorted_routed_prefill_matches_grouped_output` bleibt unverändert gültig. Performance-Abnahme erst am vollständig integrierten Referenzport, keine erneute Auswahl einzelner Bestandteile anhand von Teilbenchmarks. BK-Teilversuch 2026-09-05: Die online geprüfte, tatsächlich benötigte [MLX-0.32.2-Implementierung](https://raw.githubusercontent.com/ml-explore/mlx/v0.32.2/mlx/backend/metal/quantized.cpp) nutzt im NAX-Pfad BK=64 und für sortierte Experten BM=32 bei weniger als 64 Durchschnittszeilen je Experte. Rust Sorted-QMM nutzt BM=64/BK=32 mit M5-MPP. Der lokale allgemeine MLX-Checkout steht hingegen auf **0.32.3** (`b636898`); er ist nicht ungeprüft als Code der installierten MLX-0.32.2-Referenz zu behandeln. Nur BK von 32 auf 64 geändert und geprüft: vorhandener `qwen_sorted_routed_prefill_matches_grouped_output` mit 137 Zeilen/ungleichen Expertenbelegungen exakt bestanden. Vollständiger AR-Chat ebenfalls identische Antworten/Tokenzahlen, alle Stop/Exit0. Summary-Prefill 5,578 s, großer GPU-Buffer 3,812 s, gegenüber normal zuvor 5,291 s / 3,861 s und erneut 5,289 s / 3,848 s. PLE-pread im Summary beträgt im BK64-Lauf 552 ms statt 227 ms im ersten Kontrolllauf; die höhere Gesamt-Prefillzeit ist deshalb kein isolierter BK-Nachteil. Umgekehrt beweist die kleine GPU-Differenz ohne Wiederholungen keinen belastbaren Vorteil. **BK64 zurückgenommen**, keine unbewiesene Optimierung verbleibt im Produkt. Rohbelege: `sorted-bk64-check.log`, `qwen-bk64-ar.*` im gleichen Messverzeichnis. BM-/Experten-Worklist und BF16- statt FP32-Aktivierungsspeicher bleiben getrennte P07/P09-Kandidaten; die BK-Geometrie allein erklärt den Rückstand nicht. BF16-Speicher-Teiländerung danach umgesetzt (2026-09-05, siehe P09): Der sortierte Gather und dessen SwiGLU-Zwischenergebnis speichern jetzt BF16 direkt für den Sorted-QMM-Eingang. BM64/BK32 und die getrennten gate/up-Dispatches bleiben bestehen. Das ist kein Abschluss der ausstehenden Routing-/Fusions-/Tile-Vergleiche. **BM32 isoliert geprüft und zurückgenommen (2026-09-05):** Route-Map, Worklist- Kapazität und Sorted-Dispatch konsistent auf 32er-M-Blöcke umgestellt; der Grouped-Referenzpfad blieb bei 64. Alle acht exakten Formen bis S2048 bestanden. Vollständiger AR-Chat mit identischen Antworten: Summary-Prefill 5629 ms und großer GPU-Buffer 3977 ms gegenüber BF16/BM64 zuvor 5289–5368 ms / 3604–3662 ms bei ähnlicher PLE-Lesezeit. Kein globaler BM32-Produktpfad bleibt zurück. Der kleine Canary-Maximalwert von 1,26 ms in diesem langsameren Lauf ist erneut kein Ersatz für Performance-Messung. Kein MTP-Leistungsnachweis aus diesem Versuch. Der genauer geprüfte [MLX-0.32.2-NAX-Kernel](https://raw.githubusercontent.com/ml-explore/mlx/v0.32.2/mlx/backend/metal/kernels/quantized_nax.h) verteilt das Grid über zusammenhängende sortierte Routen und durchläuft innerhalb eines Tiles dessen Expertengrenzen; nur beteiligte SIMD-Gruppen rechnen. Rust erzeugt dagegen getrennte, je Experte aufgerundete Workitems. Bloß BM32 zu kopieren stellt diese Ausführung nicht her. Worklist-Verteilung und aktive SIMD-Gruppen bleiben innerhalb P07 zu untersuchen; der negative Versuch widerlegt keine formabhängige kleinere Tile-Strategie. **Sortierte Gate/Up-Fusion geprüft und zurückgenommen (2026-09-06):** Gemeinsames Dispatch-Grid bei unveränderten Gewichtsansichten/Tile-Mathematik besteht alle acht exakten Vergleichsformen. 16 abwechselnde Komponentenpaare: GPU-Zeit bei S2048 9,405→9,376 ms, bei S137 0,794→0,850 ms. Vollständiger AR-Chat textidentisch, Prefill4880 statt4907 ms bei gleicher PLE-Lesezeit784 ms; kein belastbarer allgemeiner Gewinn und keine Erklärung des großen Rückstands. Kein experimenteller Fusionspfad verbleibt. Belege: `local-eval-results/20260906-sorted-gate-up/manifest.md`. ### P08 — Attention/QSA-Kernel und KV-Datentransfers Kanonischer Graphstand 2026-09-07: Batch-Matmul/Softmax, Dense-SDPA-Fallback, Rows-Gather und gekachelter portabler Prefill-Gather sind verbunden; siehe „Verbundene Attention-Matrixpfade und Softmax“ und „Gekachelter portabler Prefill-Gather“, „Fused-Vector-SDPA und typisierte Metal-Konstanten“ sowie „Originale RoPE-Graphen und KV-Cache-Objektsemantik“ sowie „Direkte Sparse- Attention-Consumer im Arraygraph“. Originaler Flash-Skip-Decode und TensorOps- Prefill sind als eigene CustomKernel-Primitive geprüft. Auch die vollständige originale Blockmaskenrekonstruktion samt ScatterAxis ist verbunden und geprüft (siehe „Vollständige QSA-Blockmaskenrekonstruktion“). RoPE und gewöhnlicher KVCache sind jetzt im kanonischen Arraygraph geprüft, einschließlich Python-Objektalias/Graphdescriptor-Unterscheidung. Auch der positionale QSACache einschließlich FP32-Spiegel und Replay-Reservierungen verwendet diese Semantik (siehe „Positionaler QSACache im kanonischen Arraygraph“). Die originalen Query-/Pooling-CustomKernel sind inzwischen vollständig parametrisiert als Array-Primitiven geprüft (siehe „Parametrisierte QSA-Query-/Pooling-Primitiven“). Die gemeinsamen Float-Summen samt QSA-F32-Mittelwert sind ebenfalls portiert; GDN/PLE/HC nutzen jetzt dieselbe Reduktionsauswahl (siehe „Gemeinsame Float- Summen und QSA-Mittelwert“). Auch F32-/F16-Matmul inklusive TF32 on/off und der verbundene Eager-QSA- Score-Ausdruck sind nun im kanonischen Graph geprüft (siehe „Kanonischer Float-Matmul und verbundener QSA-Score-Pfad“). Sort/Argsort/Partition/Argpartition sind jetzt ebenfalls als kanonische Operationen geprüft; der bisherige Buffer-Argsort teilt deren Backend (siehe „Gemeinsames kanonisches Sort/Argpartition“). Die Eager-Auswahl verbindet jetzt Scores, Maskierung, Argpartition, QSACache- Spiegel und alle fünf Rückgabeformen einschließlich Kachel-Eval und Lane- Zählern (siehe „Verbundene kanonische Eager-QSA-Auswahl“). Die Verbindung zur kanonischen Indexer-Ausführung ist nun geprüft (siehe „Durchgehender kanonischer Indexer und Cache-Commit“). Der vollständige BF16/D256-Attention-Aufruf ist inzwischen ebenfalls verbunden (siehe „Verbundener Qwen-Attention-Modulaufruf“). Der gemeinsame Projektions-/Vorbereitungs-/Update-Vorlauf ist inzwischen mit fortlaufendem Cache und Eager-Auswahl geprüft (siehe „Gemeinsamer QSA-Indexer-Vorlauf und fortlaufender Cache“). Der kanonische Fused-Selektor einschließlich aller drei Ausgabeformen, Graph-Scratch-Siblings und ursprünglicher Query-Chunking-Regel ist ebenfalls geprüft; alter und neuer Aufrufer teilen dessen Backend (siehe „Fused-QSA- Selektor im kanonischen Arraygraph“). Der vektorisierte Prefill-Selektor ist nun ebenfalls als zusammenhängender Zweistufen-Graph geprüft, mit TensorOps BF16/F16 und dem allgemeinen F32-Ausdruck (siehe „Zweistufiger Prefill-Selektor im kanonischen Arraygraph“). Compiled-Indexer und Routing sind nun ebenfalls verbunden. Die dafür benötigten dynamischen Slice-/Update-Primitiven sind jetzt mit gemeinsamem Copy-/Offset-Encoder geprüft (siehe „Dynamische Cache-Fenster im kanonischen Arraygraph“); die Graphbank ist inzwischen angeschlossen. Der reine Compiled-Body samt tatsächlichem Arraygraph-Replay ist inzwischen für die erfassten Q/K-/Hidden-Fälle geprüft (siehe „Reiner Compiled-Indexer und kanonisches Graph-Replay“). Der Host-Core mit vollständigen Compile- Schlüsseln, Validierung und Statistik ist nun ebenfalls geprüft (siehe „Kanonischer Compiled-Host-Core und Engagement“). Parameter-Lebenszyklus, Cache-Commit und Routing sind nun mit 200 vorhandenen vollständigen Aufrufen, 720 Zulässigkeitsfällen und 26 zusätzlichen Lifecycle-Receipts geprüft. Weitere Compiled-Geometrien/Dtypes und die allgemeine Nicht-MPP-Score-Fusion bleiben offen. Andere SDPA-Dtypes/Geometrien einschließlich Full-SDPA sowie die vollständige Modell-/Produktintegration bleiben offen. Die folgenden Befunde zum alten Produktpfad sind dadurch noch nicht behoben. Priorität P1; nach P02, P04; Quellcodedifferenzen und Nachweislücken. - Dense Decode, Verify unter/über 16k, Prefill unter/über 32k, Sparse-Selection, Pooling, Tail und Positionierung mit MTPLX `QSACache`, `QSAIndexer` und Attention vergleichen. Rust poolt in einer CPU-Dispatchschleife und staged Dense-KV erneut. - BF16-KV, F16-Staging für FlashAttention und F32-Zwischenpuffer getrennt prüfen; kopierte Bytes, Layout/Strides und tatsächliche M5-Kernel protokollieren. - Abnahme: Masken/Indices/States und numerischer Referenzvergleich an 2048,8192, 16384,32768 und ihren Nachbarpositionen sowie partiellen Pool-Blöcken. Der entfernte 8192-Flash-Guard benötigt einen direkten numerischen Test oberhalb der alten Grenze. Ein Allokationstest für langen Kontext ersetzt keinen Attention-Test. ### P09 — Affine Matmuls, HC und Speicherformate Kanonischer Graphstand 2026-09-07: Originale affine Quantisierung sowie der installierte GatedResidual-Read einschließlich eager Norm/Matmul/Mean, Fused/V3-Auswahl und Modul-Pack-Cache sind verbunden und mit128 tatsächlichen MTPLX-Fällen exakt geprüft; siehe „Verbundener GatedResidual einschließlich eager Prefill“. Decoder-/Modell- und Produktintegration sowie Gesamtperformance sind weiterhin offen. Historische Befunde unten bleiben vom aktuellen kanonischen Port zu unterscheiden. Priorität P1; nach P01, P02, P04; Teiltests bestanden, Gesamtnachweis offen. **K-Tile/Padding/BF16-Versuch verworfen (2026-09-06):** Ein kombinierter Versuch mit gruppengroßem K-Schritt, gepaddetem Gewichtstile und BF16-Geräteingang senkte die isolierte QKV2048-Zeit auf2,654 ms, beschleunigte die vollständigen Chats aber nicht erkennbar: AR/MTP-Summary-Prefill4233/4387 ms gegenüber4214/4351 ms der vorherigen Kontrolle; GPU-Buffer2140/2151 gegenüber2160/2159 ms. Kleine Projektionsausgänge bezahlen zusätzliche Konvertierungskosten. Canary-Maxima 49/83 ms, kein allgemeiner Responsivitätsgewinn. Alle drei Antworten pro Modus Stop/Exit0 und exakt gleiche Texte, Tokens und MTP-Akzeptanz wie die gültige Rust-Kontrolle; kein erneuter MTPLX-Paritätsnachweis aus diesen Zahlen. Der erste Versuch war wegen eines übersehenen direkten GDN-QMM-Aufrufers (FP32 an BF16-Kernel) ungültig und wurde abgebrochen. Neuer Integrationstest reproduziert den Fehler bei5 Zeilen und prüft nach Korrektur4/5/32/65/2048 Zeilen inklusive Unpack exakt. Anschließend wurde die gesamte unvorteilhafte Variante zurückgenommen, nicht nur der falsche Aufrufer repariert. Test und gewöhnliche GPU-Timestamps im Operator-Test bleiben erhalten; Produkt-Binary und Metal sind SHA256-identisch zur vorherigen gültigen Wortloader-Kontrolle. Die Tests bestehen auch nach Rücknahme. Belege und Rückmessungen: `local-eval-results/20260906-qmm-k-tile/manifest.md`. **Wortweise QMM-Entpackung (2026-09-06):** Der gemeinsame Affine-QMM-Loader liest gepackte Wörter/Skalen/Bias jetzt einmal je4/8 Werte, wie der vorhandene sortierte Loader und MTPLXs `QuantizedBlockLoader`, statt pro Einzelwert. FMA/BF16-Rundung, Tile-Geometrie, Split-K und Aktivierungsformat unverändert. Alle bestehenden Projektionsgoldens einschließlich partieller Tiles bestehen. Die erweiterten Operator-Timings grenzen QKV2048 ein: MTPLX2,060 ms, Rust vorher7,272 ms, wortweise3,150 ms (Host-Aufruf und Completion, keine reine GPU-Zeit). Separat geprüfte BF16-Aktivierungsvarianten brachten keinen generellen Gewinn und sind zurückgenommen; FP32 ist damit nicht als alleinige Ursache bewiesen. Vollständiger AR-Chat text-/tokenidentisch: erster Prefill4214 statt4907 ms, größter GPU-Buffer2160 statt2656 ms, ähnliche PLE-Lesezeit792/784 ms. Canary-Max 3,962 ms; Einzelvergleich, kein GUI- oder2%-Nachweis. Weitere Form-/Layout-/ Referenzwiederholungen bleiben offen. Belege: `local-eval-results/20260906-sorted-gate-up/manifest.md`. Vollständige MTP-Kontrolle ebenfalls text-/token-/acceptance-identisch mit Stop beendet: erster Prefill4351 statt5079 ms; Decode70,622/47,038/66,224 tok/s. AR/MTP-Canary-Max3,962/3,006 ms, keine Fehler. Diese Einzelkontrollen ersetzen keine saubere zeitnahe Referenzmatrix; DeepSeek/GLM wurden dabei nicht neu gemessen. **Verifier-Zeilenspezialisierung (2026-09-06):** Der gemeinsame Wide-QMV-Metal- Helper spezialisiert nun 2/3/4 Zeilen mit konstanten Akkumulator-Indizes und unrollten inneren Schleifen wie die installierten MTPLX-Kernel. Zwölf zusätzliche echte MTPLX-Projektionshashes (QKV/Router/GDN-Control/Shared-Gate) bestehen vor und nach der Änderung; vorhandene Prefill-Goldens bleiben gültig. Vollständiger MTP-Chat bei 100%/2048/Low, ohne Profiler, mit Canary: unveränderte Texte, Tokens und Akzeptanz, Decode 70,732/47,279/68,033 statt 57,166/37,921/52,799 tok/s. Canary-Max31,552 ms, Decode-Max0,874 ms. Erster Prefill5079 statt zuvor4609 ms: keine belegte Prefill-Verbesserung. Einzelvergleich, keine gepaarten sauberen Referenzwiederholungen und keine 2%-Abnahme. Belege und Grenzbedingungen: `local-eval-results/20260905-verifier-stage-counters/manifest.md`. AR-Kontrolle ebenfalls vollständig/textidentisch beendet, Decode 48,919/48,795/48,857 tok/s, keine beobachtete Regression. Deren Canary-Max3,141 ms ist ebenfalls viel kleiner als im historischen Lauf, obwohl AR den geänderten Wide-QMV-Pfad nicht nutzt. Deshalb die verbesserten Canary-Maxima nicht kausal der Kerneländerung zuschreiben; zeitnahe gepaarte Messungen bleiben erforderlich. **Vor weiterer QMM-Optimierung belegte Abweichung (2026-09-05):** Der erweiterte Projektions-Komponententest besteht bei QKV 4-bit/g64 mit 32/64/2048 Zeilen und Router 8-bit/g64 mit 2048 Zeilen. Router 32 und 64 weichen ab. Die Referenzwerte wurden danach durch die quantisierten Projektionsmodule von MTPLXs `GatedDeltaNet` und `SparseMoeBlock` bestätigt; alle zwölf generierten Hashes entsprechen dem vorherigen direkten Bibliotheks-Diagnosetest. MTPLX bleibt das Qwen-Orakel; diese Operatorchecks ersetzen keinen Modell-/Serving-Vergleich. Belege: `tools/qwen-qmm-reference.py`, `local-eval-results/20260905-qmm-loader/` mit `mtplx-components.jsonl` und `affine-all-shapes-before.log`. Der Test sammelt alle Formfehler und schlägt weiterhin fehl; keine Golden-Hashes wurden angepasst. **Ursache inzwischen bestätigt (2026-09-05):** Im begrenzten Komponententest wurden über LLDB die vom unveränderten, installierten MTPLX angeforderten Pipeline-Namen und Dispatch-Geometrien gelesen. Router 31/32 Zeilen verwendet `affine_qmm_t_splitk_bfloat16_t_gs_64_b_8_alN_true`, Grid 16×1×20; Router 63/64 Grid 16×2×10. Danach folgt jeweils `col_reduce_small_1_reduce_sumbfloat16` mit 32×8 Threads. Router 2048 und die geprüften QKV-Matrizen verwenden dagegen NAX-QMM, ohne K-Split. Das ist nun ein Nachweis der installierten Ausführung, nicht eine Annahme anhand eines anderen Bibliotheks-Checkouts. `tools/qwen-qmm-reference.py --check-split-k` reproduziert beide Router-Goldens bitgenau mit 20 beziehungsweise 10 expliziten QMM-K-Partitionen und anschließender BF16-Reduktion. Ein ungeteilter gebatchter Kontrollfall liefert dagegen genau die bisherigen abweichenden Rust-Hashes. Die 32-Zeilen-Kontrolle muss beim kleineren K im QMM-Pfad bleiben: 64 gepaddete Eingabezeilen, anschließend Auswahl der ersten 32. Ohne diese Kontrolle wechselte der erste Diagnoseversuch die Operatorform und reproduzierte das Golden nicht. Golden-Hashes unverändert; Assertions für beide Split- und Unsplit-Kontrollfälle bestanden. Keine Timing-Abnahme unter LLDB. Diagnosebeleg: `local-eval-results/20260905-router-splitk/manifest.md`. **Split-K-Teilkorrektur umgesetzt und nachgemessen (2026-09-05):** Gemeinsamer Affine-QMM-Pfad mit formabhängiger K-Aufteilung, BF16-Zwischen-/Reduktionsrundung und wiederverwendbarem 2-MiB-Puffer. Der erste Versuch scheiterte an nativen BF16-SIMD-Overloads; nach Abgleich mit der installierten MTPLX-Abhängigkeit ist die Float-SIMD-Zwischenoperation mit BF16-Ergebnisrundung korrigiert. Unveränderte QKV-/Router-Goldens bestehen jetzt, einschließlich zuvor fehlerhafter Router 32/64. Zusätzliche tatsächliche MTPLX-Projektionsgoldens für GDN-Steuerung (N=48) und Shared-Expert-Gate (N=1) bei 32/64/2048 bestehen ebenfalls, jeweils mit Tail-/Sentinel-Prüfung; beide Reduktionspfade einschließlich 40 Partitionen sind abgedeckt. CPU-Test für Split-Policy, Alignment und Puffergrenzen bestanden. Vollständige AR-/MTP-Produktchats bei 100%, Chunk2048, Low, identischen eingefrorenen Prompts und Canary an enden natürlich. Beide Python-Ausgaben bestehen neun Fälle. Erster Prefill4,436/4,609s; Decode AR48,740/48,486/48,332 und MTP57,166/37,921/52,799tok/s. Canary max110,710/96,768ms, keine Fehler. Das beseitigt die nachgewiesene numerische Teilabweichung, nicht den verbleibenden Durchsatz-/Latenzrückstand. Gesampelte Historien ändern sich; kein isolierter Kernel-Speedup und keine 2%-Abnahme daraus ableiten. Alle Produktionsformen, QMV/QMM-Dispatch-Grenzen, HC und Kernel-Performance bleiben innerhalb P09 offen. Belege, Hashes und reproduzierbare Prüfung: `local-eval-results/20260905-splitk-implementation/manifest.md`. - Pro Operator Form, Quant-Bits/Group-Size, Packung, Akkumulator, gespeicherten Datentyp und BF16-Rundungsstelle erfassen. Rust speichert viele BF16-gerundete Aktivierungen als F32; Werteparität beweist nicht Bandbreiten-/Speicherparität. - QMV/QMM/Gather/Sorted-QMM, HC-read/mix/write, Norm/Gates, Embedding und LM-Head abdecken; aktive MTPLX-Fusionen von nicht aktivierten Experimenten trennen. - Abnahme: vorhandenen `qwen_affine_qmv_and_qmm_match_mlx_reference` und Stage-Trace- Tests wiederverwenden, keine Golden-Hashes still ändern. Produktionsformen plus Tail-/Kapazitätsfälle. Vor Änderungen Kernel-Zeit, Dispatchzahl, Kopierbytes und Peak-Transients ermitteln; Dtype-Änderungen nur mit Referenzbeweis. **Sorted-MoE-Eingangsspeicher umgesetzt, Rest offen (2026-09-05):** `kernel_qwen_route_gather_rows` und die nur dort verwendete BF16-SwiGLU-Variante schreiben gepacktes BF16; `kernel_qwen_affine_sorted_qmm_mpp` liest es als `tensor`. Bisher wurden BF16-gerundete Werte als FP32 gespeichert. Die bestehende SwiGLU-Formel/Rundungsfolge bleibt gemeinsam templatisiert; der Grouped-/Decode- und Shared-Expert-Pfad bleibt FP32. Outputs und Akkumulatoren des Sorted-QMM bleiben FP32. Vorhandene Scratch-Puffer werden wiederverwendet, ihre Kapazität wurde nicht verkleinert: kein behaupteter Peak-Allokationsgewinn. Der bestehende exakte Grouped-vs-Sorted-Test wurde auf S=5,6,7,32,64,65,137,2048 erweitert; alle Fälle bestehen mit MAE0/max0/assert_eq. Danach sechs vollständige überwachte Chats: BF16 AR/MTP, Rückkehr zu hash-identischem FP32-Metal AR/MTP, erneut BF16 AR/MTP. Alle Stop/Exit0; Antworten, Reasoning, Tokenzahlen und Draft-/Accept-/Cycle-Zahlen exakt identisch zu den vorherigen jeweiligen Kontrollen. | Modus / Pfad | Summary Prefill ms | größter GPU-Buffer ms | PLE pread ms | Prefill-Canary max ms | Prozess ms | | --- | ---: | ---: | ---: | ---: | ---: | | AR FP32 Rückmessung | 5606 | 3863.26 | 607 | 125.06 | 60572 | | AR BF16 Lauf 1 | 5289 | 3603.53 | 618 | 1.32 | 59791 | | AR BF16 Lauf 2 | 5368 | 3662.29 | 613 | 156.50 | 59900 | | MTP FP32 Rückmessung | 5770 | 3821.95 | 611 | 122.33 | 57956 | | MTP BF16 Lauf 1 | 5677 | 3741.14 | 853 | 115.85 | 59514 | | MTP BF16 Lauf 2 | 5494 | 3606.83 | 610 | 16.93 | 55938 | 100%, Chunk2048, Low, gleiche drei Prompts und fortlaufender Chat, Canary an, keine Layer-Profilierung. Der größte Prefill-GPU-Buffer ist wiederholt kürzer (AR 5,2–6,7%, MTP 2,1–5,6%). Das ist **keine 2%-Referenzabnahme** und kein Beleg, dass Decode allgemein schneller wurde. Die hohe PLE-Streuung beeinflusst auch die Gesamtlaufzeit. Insbesondere widerlegt der zweite AR-Lauf eine aus dem ersten niedrigen Canary-Wert abgeleitete allgemeine Responsivitätsverbesserung. Kein GUI-Eventloop-Nachweis; die Spitzen bleiben P04/P05/P07/P08 zugeordnet. Details/Hashes und normierte End-to-End-Decodewerte: `local-eval-results/20260905-gdn-delta/bf16-comparison.json`, `bf16-storage.md`. Zusätzliche M5-Primärquelle für die verbleibenden P07/P09-Arbeiten: [Apples MPP Programming Guide, §§2.3.1–2.3.5](https://developer.apple.com/download/files/Metal-Performance-Primitives-Programming-Guide.pdf) behandelt Tile-Reste/Occupancy, cachefreundliche Work-Reihenfolge und statische Tensor-Extents zur Vermeidung unnötiger Bounds-Checks. Das stützt die genannten Messkandidaten, beweist aber weder eine konkrete Beschleunigung unseres Kernels noch einen behaupteten FP32-Fallback auf Nicht-Tensor-Hardware. Keine weitere Geometrie-/Synchronisationsänderung mit der BF16-Änderung vermischt. **Sorted-QMM-Gewichtsloader optimiert (2026-09-05):** Der skalare Aufruf von `qwen_quant_weight` im Staging las Packed-Word, Scale und Bias für jeden einzelnen Wert erneut. Der Loader lädt diese nun einmal je Wort und entpackt daraus die 4 beziehungsweise 8 Werte mit derselben FMA und BF16-Rundung. Die installierte Konfiguration verwendet bei allen 144 Switch-MLP-Projektionen 4 Bit / Gruppe64. Der unveränderte Grouped-Kernel dient weiter als exakte Kontrolle. Alle acht Formen bestehen erneut, auch nach der Rückmessung. Nur diese Loader-Änderung bleibt zusätzlich zur zuvor geprüften BF16-Speicherung bestehen; BM64/BK32, Barrieren, Command-Buffer-Grenzen und Scratch-Kapazität bleiben unverändert. Die Wiederverwendung der Scale-/Bias-Werte ist auch im tatsächlichen [MLX-0.32.2-QuantizedBlockLoader](https://raw.githubusercontent.com/ml-explore/mlx/v0.32.2/mlx/backend/metal/kernels/quantized.h) belegt; dessen Implementierung wurde nicht als Engine-Code übernommen. Gepaarte vollständige Chats **ohne aktiven Canary** (weiterhin Supervisor, 100%, 2048, Low, bestehende drei Prompts und derselbe fortlaufende Chat): | Modus / Loader | Prefill Summary / Story / Python ms | Runtime-Decode Summary / Story / Python tok/s | größter Summary-GPU-Buffer ms | Summe Chat-Turns ms | Prozess inkl. Laden/Warmup ms | | --- | --- | --- | ---: | ---: | ---: | | AR skalar | 5297 / 794 / 840 | 48,34 / 47,83 / 48,11 | 3611,37 | 37807 | 58959 | | AR wortweise | 4310 / 620 / 622 | 48,25 / 47,83 / 47,86 | 2942,65 | 36385 | 56029 | | MTP skalar | 5508 / 828 / 868 | 52,55 / 40,00 / 69,63 | 3612,77 | 35039 | 56833 | | MTP wortweise | 4487 / 647 / 648 | 54,22 / 41,61 / 72,89 | 2943,32 | 32616 | 56390 | Mit Canary wurde der wortweise Loader separat gemessen: Summary-Prefill AR4309 ms / MTP4465 ms, großer GPU-Buffer 2940/2937 ms; Prefill-Probe max108,29/28,95 ms, keine Fehler. Der AR-Canary-an/aus-Vergleich zeigt in diesen Läufen praktisch gleiche Prefillzeit, ist aber keine allgemeine Garantie kostenfreier Messung. Die Probe bleibt optional. Alle sieben aktuellen Chats (inklusive BM32-Trial) enden dreimal natürlich mit Stop/Exit0; Startvertrag und vollständige Antworten, Reasoning, Tokenzahlen sowie Draft-/Accept-/Cycle-Zahlen stimmen mit den jeweiligen vorherigen **Rust**-Kontrollen exakt überein. Der große Prefill-Buffer wird auch ohne Canary rund18,5% kürzer. Die AR-Decode- Rate bleibt praktisch gleich. MTP-Decode und Prozesszeit sind stärker durch PLE-Lesezeit/Warmup beeinflusst (z.B. Summary PLE905 ms skalar vs607 ms neu); keinen allgemeinen Decode-Gewinn ausschließlich dem Prefill-Loader zuschreiben. Das sind gepaarte Diagnosemessungen, **keine 2%-Abnahme gegen MTPLX** und kein UI-Eventloop-Beweis. Versionen, Einzelwerte, End-to-End-Decodewerte und beide isolierten Patches: `local-eval-results/20260905-moe-tiles/manifest.md`, `comparison.json`. Reiner Matrix-/Staging-Restvergleich und P07/P08 bleiben offen. ### P10 — PLE-Streaming und Hot-Cache mit Referenzkosten vergleichen Kanonischer Graphstand 2026-09-07: PLE-Projektion/Gate und dilatierte Faltung einschließlich lazy Cache-Fortsetzung sind mit84 echten MTPLX-Fällen unmittelbar und verzögert exakt geprüft; siehe „PLE-Projektion und dilatierte Cache-Fortsetzung“. Zusätzlich ist der CPU-Staging-Hash samt roher History mit 64 Original-Receipts geprüft; siehe „N-Gram-CPU-Staging-Hash und rohe History“. Der lazy GPU-Hash bis zu den Tabellen-IDs ist mit60 tatsächlichen GPU-Receipts unmittelbar und verzögert geprüft; siehe „Lazy N-Gram-GPU-Hash bis zu den Tabellen-IDs“. Der vollständige residente `_graph_path` ist einschließlich Lookup/Dequantisierung mit24 Original-Ausgaben sofort und verzögert geprüft; siehe „Verbundener residenter N-Gram-Graph“. Der Sidecar-Gather samt Prefetch, Hot-Cache/Bypass und gemeinsamer Tabellenauswahl ist mit192 Original-Receipts in drei Auswertungsarten geprüft; siehe „Verbundener Sidecar-Gather und Tabellenauswahl“. Der verbundene Stage-Lifecycle einschließlich QA und Fehler- History ist mit136 Original-Receipts in zwei Auswertungsarten geprüft; siehe „Verbundener N-Gram-Stage-Lifecycle“. Der vollständige PLE-Aufruf einschließlich Sidecar-/Resident-Safetensors-Attach und CPU-Load ist mit144 Original-Receipts in zwei Auswertungsarten geprüft; siehe „Vollständiger PLE-Aufruf mit Safetensors-Ladeanbindung“. Modellweite Residency-/Memory-Plan-Auswahl, übrige Gewichte und Gesamtmodell-/Produkt-Integration bleiben offen. Keine P10-Performanceabnahme. Priorität P1; nach P02, P04; Unterschiede belegt, Anteil an Laufzeit offen. - Referenz `NGramEmbedding.stage`, `_SidecarGather._rows_matrices` gegen Rust `PleReader::rows`/`ple_batch_with_state`: Staging-Zeitpunkt, deduplizierte IDs, pread-Queueing, Kopien und cachefreie große Prefills prüfen. - Rust `touch` hängt jedes Mal einen Eintrag an `order`; bereinigt wird nur beim Überschreiten der Nutzdatenkapazität. Wiederholte reine Cache-Hits lassen damit Metadaten unbeschränkt wachsen. `cache_bytes` erfasst nur 100 Nutzbytes pro Row, nicht HashMap/Queue. MTPLX hält seine OrderedDict-Einträge begrenzt. - Abnahme: identische PLE-Rows über EOS/Chunk/Replay-Grenzen; begrenzte tatsächliche Cache-Metadaten bei Wiederholung. Warm-/Cold-Lookups in beiden Implementierungen messen: einzigartige Rows, Bytes, Wall-IO, CPU-Gather, Staging, GPU-Dequant/Projektion. Nur nicht überlappende kritische Zeitanteile von Gesamtzeit abziehen. - Die in MTPLX `_SidecarGather` dokumentierten M5-NVMe-Mikrosekunden sind historische Autorenmessungen; sie ersetzen keine Referenzmessung auf diesem Gerät. ### P11 — Qwen-MTP-Sampler, Depth und unnötige Arbeit Priorität P1; nach P02, P03, P04, P09; Quellcodedifferenz belegt, direkte Lazy-Übernahme vermessen und nicht beibehalten; Gesamtnachweis offen. **Target-Verteilungen gezielt verglichen (2026-09-05):** Direkte zeilenweise Materialisierung wie im aktiven MTPLX-Pfad implementiert, gegen den bisherigen Batch-Sampler geprüft und im vollständigen Produktchat nachgemessen. Alle Texte, Reasoning-Inhalte, Tokens und Draft-/Accept-Zähler bleiben identisch. Der Regressionstest prüft außerdem jeden Ablehnungs-Slot, All-Accept plus Bonus, identische weitere RNG-Ziehungen, konzentrierte/breite Masse und CPU-Fallbacks. Das ist Rust-Eager/Lazy-Äquivalenz, noch kein vollständiges MTPLX-Sampler-Orakel. Die isolierte Messung mit 32 alternierenden Paaren zeigt aber: vier gebatchte Verteilungen kosten rund 0,80ms; lazy 1/2/3/4 benötigte Zeilen rund 0,53/1,02/1,49/2,04ms. Nur sofortige Ablehnung profitiert. Die Produktänderung wurde deshalb zurückgenommen; Vergleichstest bleibt. Der aktuelle Produktionscode entspricht nachweislich wieder dem vorherigen Stand, CLI neu gebaut. Eine schnellere äquivalente Ausführung ist zulässig; ein anderer Aufrufplan allein ist kein Fehler. Der vollständige wiederhergestellte Harness-Pfad wurde anschließend mit vorhandener MTP-Profilierung ausgeführt, erneut mit exakt identischen Antworten/Zählern. 588 Vier-Zeilen-Verifikationen inklusive Warmup: Median Encoding-Wall3,217ms, anschließendes GPU-Warten42,025ms, Readback0,004ms. Host-Zeitgrenzen, keine isolierten Kernelzeiten; Profiling und Canary an. Der große Restaufwand liegt damit im GPU-Verify-/Submission-Pfad, nicht im Auslesen der Verteilungen. P05–P09 sind dafür weiter zu lokalisieren; keine Performance-Parität behauptet. Belege und reproduzierbare Prüfungen: `local-eval-results/20260905-lazy-target-distributions/manifest.md`. - Draft-D3 wie Referenzdefault vergleichen. D1..D5-Unterstützung ist eine getrennte Funktionslücke, kein Grund, während des Default-A/B heimlich die Tiefe zu ändern. - Voller Verify-Block: Rust berechnet/verliest alle Target-Verteilungen; MTPLX `generation.py` materialisiert lazy bis zur ersten Rejection bzw. Bonusposition. CPU/GPU-Sync, Top-k-Pfad und Full-Vocab-Fallback jeweils zählen. - RNG nicht pauschal als verschieden bezeichnen: Rust enthält bereits NumPy-kompatibles SeedSequence/PCG64. Draw-Reihenfolge, Softmax/top-p/min-p, Rejection und Residual müssen auf gleichen Logits/Drafts geprüft werden. - Abnahme: deterministische Akzeptanz-/Korrekturfälle, identische Zufallsziehungen, gleiche Verteilungssemantik; pro Zyklus Drafts/Accepted/Bonus/Correction, Forward- Breiten und Zeiten. Hohe Python-Akzeptanz ist eine Messhypothese, keine Garantie. ### P12 — Qwen-MTP-Commit, Fallback und vollständiger Abschluss Priorität P0; nach P03, P04, P06, P11; potenziell schwerer Fallback belegt. Kanonischer Graphstand 2026-09-07: Validierung und reine GDN-Capture-Rekurrenz sind mit den vorhandenen Array-Primitiven verbunden und gegen 26 tatsächliche MTPLX-Commit-/Decode-Receipts geprüft. Globale Validierung vor Mutation, QSA-/PLE-Zweige, Ablehnungszähler, Rollback-/Repair-Orchestrierung und Produktintegration bleiben offen; siehe „GDN-Capture-Commit mit nachfolgendem Decode“. Die folgenden Befunde betreffen weiterhin den alten Produktpfad. - `restore_or_replay` fällt bei Capture-Fehler auf `replay_tokens` zurück, das nach Reset den **gesamten bisherigen Kontext tokenweise** ausführt. Der Fehler erscheint nur in stderr, nicht als eindeutig gezähltes Laufzeitereignis. - Gegen MTPLX `commit_verified_window`, Conv-Tape-Rekurrenz, Pending-Correction und begrenzte Repair-Pfade abgleichen. Nicht bloß den Fallback schneller machen: Ursache unvollständiger Captures und korrekte Zustandsgrenze bestimmen. - Abnahme: kein unbemerkter Full-Context-Replay; gezielt ausgelöste Rejections an jeder Draftposition, alles akzeptiert, EOS, Cancel, Kontextende und Save/Restore. KV/GDN/PLE/MTP-History nach Commit mit Target-Referenz vergleichen; vorhandenen `qwen_mtp_matches_target_and_restores_its_cache` erweitern statt neuen Teststack bauen. ### P13 — DSpark-/GLM-Sampling-Vertrag und effektive Einstellungen Priorität P0; nach P01, P02 für die Messabnahme; Settings-Korrektur und Receipt-Tests bestanden, End-to-end-Messung offen. - DS4 `ds4.c:61906` wählt Metal-Confidence 0,6; `:66603` hebt nur bei stochastischem Exact Sampling den nicht expliziten Wert auf mindestens 0,8. Rust setzte vorher schon normal 0,8 und löste die Exact-Anhebung beim Laden statt pro Turn auf. Jetzt gemeinsame Auflösung in `EngineSpeculativeSettings::dspark_confidence_for_temperature`, verwendet von beiden Proposal-Aufrufern und dem Harness-Receipt. Explizite Werte bleiben unverändert, einschließlich 0 und 0,7. Kein Eingriff in gespeicherte Konfigurationen. - Harness-Start enthält nun Sampling-Kategorie (`target_only`, `greedy`, `opportunistic`, `exact`), Basis-/Turn-Confidence, explizit/automatisch, Strict-/Exact-Flags und integriertes MTP-Timing. UI-Hilfetext korrigiert; Performance-Fixture bezieht ihren Default aus denselben Produkt-Settings. - DSpark opportunistic/strict/exact und GLM opportunistic/exact gesondert erfassen. Rust GLM-Sampled-Dispatch leitet an greedy draft matching weiter; das entspricht der opportunistischen Kategorie, nicht dem optionalen Exact-Modus der Referenz. - Abnahme: Tabellengetriebener Test für fehlenden Wert, expliziten Wert, Exact und Quality/Strict. Harness-Receipt enthält effektive Schwelle und Semantik, nicht nur `acceleration.enabled`. Fehlende Exact-Unterstützung ausdrücklich markieren. Verifikation 2026-09-05, ohne GPU-Modelllauf oder breite Gates: - Regression vor Korrektur: Default-Test scheitert mit Ist 0,8 / Soll 0,6. - `cargo test --release --bin ds4-server settings::tests::`: 8 bestanden, einschließlich fehlender/gesetzter Werte und Exact bei Temperatur 0/1. - `cargo test --release --bin ds4-server model_eval::tests::`: 8 bestanden, einschließlich Receipt-Modi, Quality/Strict, GLM/Qwen und abgeschalteter Acceleration. - `cargo test --release --bin ds4-server engine::metal::tests::dspark_`: 2 CPU-Tests bestanden; modellabhängiger Test blieb explizit ignored. - `git diff --check`: bestanden. Keine Durchsatzverbesserung aus diesen Tests abgeleitet. Vor der neuen DSpark-Messung bleiben P02/P03/P04 maßgeblich. ### P14 — GLM-MTP tatsächlich batchen wie DS4 **Produktpfad umgesetzt, Referenz-Performanceabnahme offen (10.09.):** `local-eval-results/glm-two-row-20260910.Y1SbdU/{manifest.md,comparison.json}` enthält echten Zwei-Zeilen-Forward, Row0-Head, KDA-GPU-Backup/Restore, Rejection-Replay und Rewind auf null/ein behaltenes Token. Vorhandene Batch-Kernel laufen mit einem wiederverwendeten Zwei-Zeilen-Workspace; HC-Expansion leitet ihre Zeilenzahl aus Bufferbytes ab, deshalb darf hier nicht die 2048-Zeilen-Allokation verwendet werden. Speicheradmission ergänzt. Tests an Frontier12/Context128 und Frontier4095/Context8192 bestehen Annahme, Ablehnung, Rewind, Cap1 und bereits gesetztes Cancel. Replay-KDA/Logits sind bitgenau skalar; der Grenzfall schaltet wie DS4 auf indexierten Batch um. Der normale Vorher-Chat scheiterte an einem schon vorhandenen zu kleinen skalaren Auswahlbuffer im Dense-Compact-KV-Pfad. DS4 reserviert dafür Context- statt nur Top-K-Kapazität; gemeinsame Rust-Allokation korrigiert. Danach vollständige AR/MTP-Chats bis EOS bestanden, beide Python-Ausgaben inklusive 5 Assertions und 5011 unabhängigen Fällen korrekt. Kein Speedup aus dem abgebrochenen Vorher-Lauf. Decode AR 22,278/21,637/22,443 und MTP 22,576/19,350/30,768 tok/s; unterschiedliche Antworten/Historien, keine direkte DS4-Messung oder 2%-Abnahme. Prefill-CB-Maxima 5,983s AR / 4,419s MTP bleiben ein offener Responsivitätsbefund; Canary aus, kein GUI-Stall-Nachweis. Aktueller DS4-Quellstand ec7642c: nichtfinale 2048er-Chunks können ebenfalls ohne Layer-Flush laufen (>2048 oder Logits+>8 ist die Bedingung); daher nicht blind zusätzliche Flushes als Lösung übernehmen. P15 weiter prüfen. Zusätzlicher P13-Messpunkt (ursprünglicher Befund): GLM-MTP-Zähler werden mit Resident-State getauscht, die Harness behandelt sie aber als Engine-Lifetime-Counter. Warmup→neuer Chat kann deshalb den ersten Turn unterzählen. Vor Akzeptanzraten-Abnahme angleichen; Rohwerte erhalten, keine bereinigten Quoten als Beweis ausgegeben. **P13-Zählerscope korrigiert und geprüft (10.09.):** `local-eval-results/glm-counter-scope-20260910.HgghwY/manifest.md` enthält den roten/grünen Sessionwechsel-Test und den vollständigen Produkt-MTP-Chat. Die fünf kumulativen Zähler bleiben nun auf der aktiven Engine, während Cache und Draft-Zustand mit dem Chat wechseln. Test prüft Rückkehr in den alten Chat, monotone Zähler und bitgleichen rekurrenten Zustand. Alle drei Antworten und Tokenzahlen stimmen per `cmp` mit dem vorherigen Lauf überein. Summary zählt nun385 statt377 Zyklen und241 statt236 Accepts: Warmup8/5 wurde zuvor fälschlich abgezogen. Story/Python unverändert. Keine neue GPU-Arbeit; CB-Zahlen gleich. Kein Performance-Pass: Decode22,336/18,682/29,075 tok/s, Prefill-CB-Max4,451s; Canary aus. Wächter Exit0, kein laufender Modellprozess. Direkte DS4-Laufzeit- Referenz und sechszellige Abnahme bleiben offen; Klärung der AGENTS.md-Regel gegen Kompilieren/Aufrufen des C-Referenzprogramms erforderlich. Keine C-Produktintegration vorgesehen oder vorgenommen. Fokussierte GPU-/CPU-Tests, Release-Clippy, Build, Format-/Diffcheck bestanden. Keine C-Integration, kein Bundle/Commit/Push, Gesamtziel weiterhin offen. **Ursprünglicher Befund und Abnahmekriterien:** Priorität P1; nach P04, P13; Quellcodedifferenz belegt. - Rust `eval_speculative_greedy` führt beim kompatiblen Draft erst `eval_glm53_capture(token)` und bei Acceptance nochmals `eval_glm53_capture(draft)` aus. DS4 `ds4_session_glm_spec_cycle_impl` (`ds4.c:64176`) verifiziert das Paar in einem Zwei-Zeilen-Batch mit KDA-Backup/Restore. - Target-Forward, Draft-Head, Rollback und History separat vergleichen. Acceptance allein beweist keinen Geschwindigkeitsgewinn, wenn Target-Arbeit nicht amortisiert wird. - Abnahme: echter 2-Row-Verify-Aufruf im Receipt, korrekter KDA/DSA/KV-Zustand bei Match/Mismatch/Cancel, gleiche Sampling-Kategorie und keine Output-Korruption. Danach vollständige GLM-AR/MTP-Chats neu messen; alte überlappte Daten nicht verwenden. ### P15 — DS/GLM-Scheduling, Kaltstart und gemeinsame Runtime abgleichen **Aktiver GLM-Pfad und durchgehender Canary geprüft (10.09.):** `local-eval-results/glm-scheduling-canary-20260910.T1ABR1/{manifest.md,comparison.json}` enthält zwei vollständige AR/MTP-Chats bis EOS bei Power100/Low und Canary an. Ausgabe einschließlich Tokens/Thinking/Abschluss ist jeweils exakt zum letzten Canary-off-Lauf. MTP854/AR935 Proben, keine Fehler, Maxima302,140/251,040ms im Prefill; Decode-Maxima27,847/0,929ms. Keine Probe über2s. Ein mehrsekündiger Modell-Command-Buffer blockiert diese unabhängige GPU-Probe nicht automatisch gleich lange. Keine echte GUI-Eventloop- oder Referenz-Latenzabnahme daraus. Wichtige Quellzuordnung: Im aktuellen DS4 ist expanded/full-KV deaktiviert; GLM5.3 benutzt auch für den dichten Compact-Prefix den indexed-Graph. Dieser übergibt die Batchtokenzahl als `command_rows`, nicht `pos+rows`. Deshalb passt die vorhandene Prefill-Flush-Bedingung für die aktiven <=2048er-Chunks; die anderslautende Bedingung des nicht aktiven full-KV-Pfads darf nicht blind in Rust übernommen werden. Konkrete Restabweichung im residenten skalaren Decode: DS4 flusht periodisch alle4 Layer (ohne letzten Layer), Rust nur einmal nach4. SSD-Expert-Streaming hat eigene Command-Ownership-/Sync-Regeln und ist separat abzugleichen. Außerdem Host-Encoding-Progress von abgeschlossener GPU-Arbeit trennen. Das Manifest enthält die zusammenhängende Folgearbeit samt Abnahmen. **GLM-Teilprefill: HC-Arbeitsmenge korrigiert (10.09.):** `local-eval-results/glm-hc-bounds-20260910.BKGvSr/manifest.md` dokumentiert den roten/grünen Produktpfad-Test. Dense und indexed DS4-Prefill begrenzen HC-/Collapsed-Ausgaben mit token-genauen Views. Rust übergab bisher die gesamte Workspace-Kapazität, obwohl sowohl HC-Expansion als auch Split/Sum ihre Zeilenanzahl aus den Ausgabebytes ableiten. Der Regressionstest weist echte Schreibzugriffe auf unbenutzte Zeilen nach. Fünf einmalig pro übergroßem Batch erzeugte, nichtkopierende Views begrenzen jetzt sämtliche vier HC-Aufrufe je Layer; der gemeinsame Pfad gilt für normalen Prefill und Zwei-Zeilen-Verifikation. Alle fünf Guard-Ausgaben sowie die vorhandenen Rewind-/Rejection-/Counter- Prüfungen bestehen. Keine neuen Flushes, keine Chunkverkleinerung, kein anderer Kernel oder Sampler. Das beweist unnötige Arbeit, nicht deren Anteil an den mehrsekündigen Command Buffers oder an GUI-Stalls. Eine zuerst vermessene Variante mit Views auch für bereits exakte Workspaces wurde wegen schlechterer Laufzeiten nicht beibehalten; Vorher-/Kontrollbinary sind hash-identisch. Die gezieltere Variante besteht alle Guards mit 2048er-Workspace und den vollen MTP-Chat mit exakt gleicher Ausgabe. Prefill Summary/Story/Python 6418/269/311ms gegenüber 6648/394/452ms im ersten Vorher-Lauf, Decode22,500/19,173/30,988tok/s. Gesamt96,901s liegt zwischen den beiden Vorher-Läufen99,559/95,288s, deshalb kein belastbarer Gesamt-Speedup. Maximaler CB weiterhin4,424s; Canary aus. AR-Chat ebenfalls natürlich beendet, Tokens/Text/Thinking/Abschluss identisch zum vorherigen AR-Beleg; Prefill8614/278/333ms, Decode21,648/20,967/21,778tok/s, Max-CB6,150s. Kein frisches AR-Referenzpaar. Zwischenstände, Messstreuung und ausstehende Responsivitätsabnahme bleiben sichtbar. P15/P16 offen. Priorität P1; nach P01, P04, P13; Source-Inventar vorhanden, Detailbeweis offen. - DS4 `ds4.c:35309` teilt nichtkleine Prefills auch wegen echter Progress-Callbacks. GLM-Referenz `:47379` berechnet Stage-Sync, Layer-Flush, Progress-Flush und Drain getrennt. Rust GLM koppelt Flush an Logits-Anforderung; Zwischenchunks können anders laufen. DeepSeek/GLM nicht blind auf eine Qwen-spezifische Policy umstellen. - Prefill/Decode-Power, echte Pausen bei <100%, Keine-Pause bei 100%, SSD-/Resident- Varianten, finale und nichtfinale Chunks sowie Cancel-Keepalive prüfen. - Kalten UI-`ping` separat reproduzieren: Modell-/Pipeline-Laden, Systembootstrap, Restore und erster Prefill. Kein Warmup darf diesen Fehler unsichtbar machen. OS-Pagecache nicht global leeren; Prozess-kalt und tatsächlich SSD-kalt unterscheiden. - Abnahme: Dispatch-/Wait-/Progress-Trace je Phase gegenüber DS4-Code; kalter Ping und warmer Chat enden ohne unbeobachtete Phase. Release-Bundle- und Harness- Buildidentität dokumentiert. Noch fehlende direkte DS4-Laufzeitreferenz transparent halten; C-Inferenz wegen Projektvorgabe nicht eigenmächtig starten. ### P16 — Gezielte Änderungen erneut messen und Gesamtmatrix abnehmen Priorität P1; nach den relevanten P01–P15; offen. **Aktuelles interaktives Test-Bundle bereitgestellt (10.09.,22:32):** `make bundle` und strikte Codesign-Prüfung bestanden. Das Bundle enthält den zuletzt vermessenen Release-Code und identische Metal-Ressourcen; der genaue signaturbedingte Mach-O-Unterschied ist im Manifest `glm-scheduling-canary-20260910.T1ABR1` nachgewiesen. `model-eval --help` direkt aus dem Bundle besteht ohne Modell-/GUI-Start. Der bisherige September6-Build ist ersetzt. Kein tatsächlicher GUI-Eventloop-/Kaltstart-Test und keine sechszellige Performance-Abnahme; die Anwendung ist als Teststand verfügbar. **Neue Plain-Chat-Referenzdiagnose (2026-09-05):** Unveränderter MTPLX-Server, exakte eingefrorene Eingabeprompts und Samplerwerte der Rust-Diagnose, keine zusätzliche leere Systemnachricht; AR und MTP sequenziell, vollständiger Summary/Story/Python-Chat. Alle Antworten natürlich beendet, Python-Prüfungen bestanden, beide Supervisor exit 0. Erster Summary-Prompt identisch 2617 Tokens: MTPLX-Prefill 2,455 s AR / 2,528 s MTP versus Rust 4,483 / 4,697 s mit sogar 30 bereits gecachten Tokens. Referenz-MTP-Decode 71,403/55,527/90,376 tok/s versus Rust 53,976/38,874/61,596. Kein Pass: Canary an, jeweils Einzelmessung, andere gesampelte Historien, Cache-Arbeit und Stop-Token-Zählweise. MTPLX zählt das Stop-Token mit, Rust nicht; dieser Messvertrag gehört zu P04, keine unautorisierte Änderung der Produktzähler. Referenz-Canary max 4,679/4,540 ms gegenüber Rust 102,483/84,761 ms. Der Rückstand bleibt sichtbar, auch ohne Mehrsekunden-Stall. Details, Rohdaten, Hashes und Grenzen: `local-eval-results/20260905-plain-reference/manifest.md`. - Während der zusammenhängenden Qwen-Portierung: Referenz-/Regressionstests für Funktions-, Kernel- und State-Abdeckung; Änderungen und Restabweichungen hier nachtragen. Gesamt-Performancevergleich erst nach vollständiger Integration, nicht als Auswahlverfahren für einzelne Referenzbestandteile. - Endmatrix: DeepSeek AR/DSpark, GLM AR/MTP, Qwen AR/MTP. Leistung 100%, Chunks 2048 soweit Produkt/Referenzvertrag, kleinster aktiver Thinking-Level; Sampler und MTP-Einstellungen innerhalb jedes Referenzpaares identisch, keine künstliche Gleichsetzung verschiedener Modellverträge. - Pro Zelle separater Warmup, danach Summary README → Story → Python als ein ongoing Chat bis EOS. Zusätzlicher kalter Ping; keine Gesamtzeitbegrenzung. Startup-/Fortsetzungswatchdog, echte Fortschrittsereignisse, Speichergrenze, Prozessüberwachung und genau ein GPU-Modell gleichzeitig. - Saubere Performance-Läufe Canary aus, separate vollständige Responsiveness-Läufe Canary an; mindestens drei gepaarte Wiederholungen in wechselnder Reihenfolge. Bei Messstreuung in Größenordnung der 2%-Grenze kein Pass aus einem Einzelwert. - Tabelle je Turn: neue/cached/Output/Thinking-Tokens, Load/Restore/Prefill/TTFT, Prefill- und Decode-tok/s, Gesamtzeit, MTP-Akzeptanz und Zeitzerlegung, GPU/Host/UI-p50/p95/p99/max, Peak-Footprint, IO und Abschlussursache. - Inhaltliche Abnahme: Summary deckt README ab; vollständige Story ohne Rückfrage; Python-One-shot anhand vorab festgelegter kleiner funktionaler Assertions prüfen. Generierten Code vor Ausführung prüfen und isolieren, keine Tools/Netzwerkrechte. - Durchsatzziel: mindestens 98% der matched-work Referenzgeschwindigkeit; schneller erlaubt. Gesamtzeiten der natürlichen Chats zusätzlich zeigen, aber unterschiedliche Antwortlängen nicht als Kernelregression ausgeben. Latenz separat abnehmen; ein schneller Durchschnitt kompensiert keinen Mehrsekunden-Stall. Nutzerentscheidung vom 2026-09-10: Die beobachteten 2,6% Rückstand bei **Qwen Summary ohne MTP** sind als eng begrenzte Ausnahme akzeptiert, ausschließlich wenn alle übrigen Punkte erledigt sind und die produktive Anwendung ansonsten Funktions- und Performance-Parität erreicht. Keine allgemeine Toleranzerhöhung, keine vorgezogene Abnahme und keine Ausnahme für Stalls, Prefill oder andere Turns. ### R01 — MTPLX-Speculation als zusätzliche Optimierungsquelle für DS/GLM Separater Recherche-Task; nach belastbarer DS4-Baseline P13–P16, kein Wechsel des Golden Masters und keine Voraussetzung für die erste Paritätsabnahme. - Im gepinnten MTPLX existiert ein eigener DeepSeek-V4-Backendpfad (`mtplx/models/deepseek_v4.py`, Registrierung `mtplx/backends/registry.py:299`). Native MTP-Köpfe dort nicht ohne Prüfung mit DSpark/DFlash gleichsetzen. - Generische Techniken wie batched verify, lazy distributions, begrenzte Capture-Commits, Deferred Repair und Draft-Tiefensteuerung auf Übertragbarkeit für beide Modelle untersuchen. Eine native GLM-5.3-Flash-Unterstützung wird hier nicht behauptet; allgemeine Techniken können auch ohne diesen Backendpfad relevant sein. - Ergebnis: kurze Kandidatenliste mit exakter Quellstelle, Artefakt-/Draft-Vertrag, unveränderter oder abweichender Sampling-Semantik, gemessenem Referenzvorteil und kleinstem A/B-Versuch. Nicht passende oder nur beworbene Vorteile aussortieren. - Abnahme einer späteren Übernahme weiterhin gegen **antirez/ds4**: gleiche Funktion, keine schlechtere Responsiveness, belegter Performancegewinn. Kein Download anderer Artefakte und keine Umstellung auf MTPLX-Runtime als Abkürzung. ## Reihenfolge und Fortschrittsführung Zuerst P01–P04 als belastbare Vergleichsgrundlage. Danach P05/P06 für den belegten Qwen-Prefill-Fehler und P12 für unbeschränkte Repair-Kosten; P11 liefert dafür den Sampler-/Acceptance-Nachweis. P07–P10 schließen die übrigen Kernel-/IO-Unterschiede. P13 muss vor DSpark-Vergleichen erledigt werden, P14/P15 vor der DS/GLM-Freigabe. P16 misst den vollständig integrierten Qwen-Port und die komplette Modellmatrix; die frühere Mikrobenchmark-Auswahl pro Änderung ist aufgehoben. Pro Task werden Status, konkreter Patch, Referenz-/Arbeitsstand, Testbefehl, Rohdatenpfad, vorher/nachher und verbleibende Differenz ergänzt. Eine Abweichung verlässt die Liste nur durch Nachweis oder ausdrückliche Nutzerentscheidung, nicht durch Weglassen aus dem nächsten Bericht.