
# ENTWURF — delta_stueck: der Haeppchen-Weg fuer qwen35 / qwen35moe
Stand 27.08.2026 (Qwirbel, allein — keine Agenten)

## Die Entscheidung (mit Begruendung)
Ziel laut PLAN-ALLE-ARCHITEKTUREN.md Z.648 ist der Haeppchen-Vorlauf:
mehrere Marken je Dispatch statt einer. Fuer die DeltaNet-Hybriden baue ich
dafuer EINEN Kernel, der die Marken-Schleife INS eigene Innere verlagert —
echte Rekurrenz, sequentiell je (h,o)-Spalte von S, aber nur EIN Dispatch
fuer das ganze Haeppchen. Der Mathematik-Kern bleibt woertlich der bewiesene
aus spirv.baue_delta_schritt (tests/test_delta_schritt.py, 25.08., gegen
llama.cpp-CPU bewiesen).

Die matmul-Form der chunked-delta-rule (llama.cpp build_delta_net_chunking,
CS=64, cumsum, decay-mask, ggml_solve_tri) wird HEUTE NICHT gebaut: sie
braucht drei neue nichttriviale Kernel (cumsum, Dreiecksmaske, tri-solve)
und sortiert Fliesskomma-Summen um — nicht bitgleich. Sie bleibt als
Tempo-Schritt 2 offen (ehrliche Absage mit Grund, REGELN R2).

## Kernel-Vertrag
spirv.baue_delta_stueck(gruppe=128):
  Puffer 0 S (hv,dk,dk) RW, 1 k_n (M,hk*dk), 2 q_n (M,hk*dk),
  3 v (M,hv*dk), 4 g (M,hv), 5 beta (M,hv), 6 out (M,hv*dk).
  Push [dk, hk, M, skal_q-Bits]. Gruppen (hv*dk,1,1), je gruppe Faeden.
  Je Marke t exakt der Rumpf von baue_delta_schritt:
    s_i = S[h,i,o]*g[t,h]; lese = sum_i s_i*k[t,(h%hk)*dk+i];
    d = beta[t,h]*(v[t,h,o]-lese); S[h,i,o] = s_i + k[t,..]*d;
    out[t,h,o] = sum_i S[h,i,o] * (q[t,(h%hk)*dk+i]*skal_q)
  (h%hk) = getilete GQA-Koepfe wie ggml (q_voll[w*hk+j]=q_n[j], derselben
  Tilungsaufbau wie heute per zeilen_einsetzen-Schleife) — das
  Tilungs-Feld faellt ganz weg. qi*skal VOR der Multiplikation mit s2:
dieselbe Rundungsfolge wie breit()+delta_schritt heute => bitgleich
konstruierbar. Fundstelle: BAUPLAN/src__models__delta-net-base.cpp
(autoregressive Form); die Marke-Schleife darueber ist Wiederholung,
nicht eine neue Formel.

## Bauplan-Aenderungen (qwen35.py + qwen35moe.py, gleiches Muster)
1. embed(marken) -> (M, dim), je Marke nur ihre Zeile (wie gemma3, aber
   ohne Skala — qwen35 skaliert die Einbettung nicht).
2. _linear_block M-reihig: wqkv/wz/walpha/wbeta als M-Zeilen-Matvec;
   alpha/beta als EIN hole() je Block je Haeppchen (M,hv), g/beta auf der
   CPU vektorisiert (elementweise identisch zum Einzelschritt), EIN Upload.
3. Conv kausal ueber Stapel: stapel = (conv_k-1) Alt-Ring-Zeilen + M neue
   qkv-Zeilen; y = sum_u zeilen_ausschnitt(stapel,u,M)*conv[u];
   danach ring = letzte conv_k-1 qkv-Zeilen (zeilen_einsetzen aus Sicht).
4. delta ueber netz.delta_stueck (k_n/q_n UNGETILET, skal im Push).
5. _voll_block M-reihig nach gemma3._attn: rope/cos/sin je M Zeilen,
   cache.merke(ab=pos), aufmerksamkeit(q_versatz=pos, kv_marken=pos+M).
6. qwen35moe._moe M-reihig nach dem gemma4moe-Vorbild vom 27.08.
   (linear_moe x_zeilen = mul_mat_id) — dort abschauen, nicht neu erfinden.
7. schritt_viele + schritt = schritt_viele([t]) (kein zweiter Weg, R22);
   Adapter.vorwaerts schneidet N.PREFILL_STUECK und gibt die LETZTE Zeile
   zurueck (logits_np bleibt unberuehrt).
8. Beweis: neuer Test delta_stueck vs M x delta_schritt BITGLEICH
   (mehrere M, Aufteilungen, M=1, hv>hk-Tilung); test_prefill.py um
   qwen35/qwen35moe erweitern — pruefen, ob mini_gguf die Familie schon
   schreiben kann, sonst dort erweitern. Danach Tempo A/B min 3 Laeufe +
   Dispatch-Zahl (PROMPTS-GLM-2026-08-27.md, PROMPT B).
9. R1: Suite NACH der letzten Aenderung laufen lassen; PLAN Z.648 und
   PROJEKT.md ehrlich aktualisieren (matmul-Form bleibt offen).
