25 lines
2.3 KiB
Markdown
25 lines
2.3 KiB
Markdown
# Chantier 4 — GDN chunkwise prefill (3.5, push 93→~150)
|
||
|
||
## Base mesurée (26/05, fork ql, t8/b512/fa)
|
||
prefill plat: 93 @512, 97 @2k, 91 @8k. dense 285→182 (quadratique). croisement RAG ~24-28k. decode O(1) stable. Cible: prefill linéaire mais lent = recurrence sérielle, pas BW.
|
||
|
||
## Le kernel actuel (gated-delta-net-ops.c:573 pp_thread)
|
||
Par tête (parallèle H*n_seqs), state S×S (S_v≤128). Pour chaque token t: gate-decay des S lignes, delta=(v−S·k)·β, update rank-1 S+=k⊗δ, out=S·q. = 3·S² flops/token, sériel sur n_tokens. C'est l'ancre.
|
||
|
||
## Chunkwise (delta rule, CUDA/Vulkan le font)
|
||
Chunk C=64: intra-chunk = matmuls C×S triangulaire, inter-chunk = state. Les rank-1 sériels → GEMM C×S batchables → HMX 32×32. n_tokens/64 étapes au lieu de n_tokens.
|
||
|
||
## Paliers (mesure à chaque)
|
||
1. pp_thread chunked **f32** bit-exact (réutilise cache, pas HMX). Valide ggml ref + bench. Gain cache seul?
|
||
2. inner GEMM → HMX fp16, comparer dérive vs CPU (prefill tolère, KV only). Bench 93→?
|
||
3. VTCM pour state inter-chunk (déjà au tg). Cible 150.
|
||
Risque: HMX fp16 accum non bit-exact — OK prefill (decode CPU exact). Frontière, aide partielle structure/debug.
|
||
|
||
## P0 fait (26/05): oracle = `test-backend-ops -o GATED_DELTA_NET -b HTP0` = 28/28 OK (hs64, 256tok, kda). Gate régression. K>1 non-sup=decode, hors prefill. baseline pp512=93. build: ninja .../libggml-htp-v79.so. P1 en cours.
|
||
|
||
## P1 — chunk f32 (réf code: pp_thread:573-695)
|
||
Récurrence/token: S(SxS)*=gate ; sum=S·k ; δ=(v-sum)·β ; S+=k⊗δ ; out=S·q. Helpers: gdn_mul_dot4_f32 (decay+S·k), gdn_add_scaled_dot4_f32 (rank1+S·q), kda=vecteur/scalar gate. Sériel sur n_tokens = ancre.
|
||
Chunkwise C=64: A=tri(K K^T) corrigé β,gate → W=(I-A)^-1 ; intra: out += (Q K^T tri)·V ; inter: out += Q·S, S=gate·S+K^T(βV). 3 GEMM CxS au lieu de 3·S² rank1/tok. f32 d'abord, bit-exact oracle, gain cache. C=64 mappe tuile HMX. Gate: GGML_HEXAGON_GDN_CHUNK=1 opt-in tant que pas validé.
|
||
Étapes: (1) refactor pp en boucle de chunks C=64 (1 chunk=ancien path) -> 28/28 inchangé. (2) intra-chunk parallèle f32. (3) bench. risque=δ inter-chunk gate, garder pp_thread comme fallback C=1.
|
||
P1.1 FAIT: chunk loop C=64 in gated-delta-net-ops.c:626, calcul identique, oracle 28/28 + pp512=98 = neutre. ql=fork local (.git propre). Suite: intra-chunk GEMM. Build pp512 = ~30s ninja htp-v79.
|