code wiki / (root) / nx_kda.nx

nx_kda.nx source

↩ module page · 57 lines · 3089 B

1// nx_kda.nx -- KDA LANE SUPPORT: the KDA:MLA interleave schedule. Deliberately does NOT reimplement the 2// KDA kernel. 3// 4// WHY THIS FILE IS SMALL. An earlier pass this session built a full KDA numeric core here, then found that 5// _hdl_build/nx_nofloat_kda.nx already implements it -- and better: Q16 not Q10, a whole-sequence forward 6// rather than single steps, scratch hoisted out of the step loop, DRY reuse of nx_nofloat_linattn. The 7// duplicate was removed rather than left to rot beside it. It was also a live hazard: both files defined 8// kda_write and kda_step with DIFFERENT signatures, so any organ importing both would have broken. 9// 10// CORRECTION (same session, after the above was written): the schedule below is ALSO a duplicate. It was 11// claimed here as "the part nobody had built", and that was wrong -- `_hdl_build/nx_nofloat_k3interleave.nx` 12// implements the 3:1 structure more completely, assembling a real [KDA,KDA,KDA,MLA] stack from the proven 13// KDA and MLA organs, and its gate T5 asserts the schedule mechanically (6 KDA : 2 MLA over 8 layers, MLA 14// at l=3,7). That organ is now BUILT and RUN, 6/6 GREEN. 15// 16// THE AUTHORITATIVE ORGANS ARE THEIRS, NOT THIS FILE. Do not adopt the schedule below for new work; use 17// nx_nofloat_k3interleave. What survives here that is genuinely NOT covered elsewhere is only the 18// FACTORISATION IDENTITY proved in nx_kda_gate T1-T3, plus kdasched_kv_cut_permille, which turns the 19// reported 75% KV cut into a computed number (750 permille) rather than a claim. The schedule functions 20// remain solely because that permille calculation is built on them. 21// 22// Kept deliberately small and clearly labelled rather than silently left to rot beside the real thing. 23// 24// Names are prefixed kdasched_ so this can never collide with the kernel's kda_* symbols. 25// Kernel: _hdl_build/nx_nofloat_kda.nx (gate 5/5 GREEN, first ever built + run 2026-07-31). 26// license_tier: ORIGINAL No hw writes (Rule 26). 27import "nx_syscalls.nx" 28 29const KDASCHED_LINEAR: i64 = 0 30const KDASCHED_FULL: i64 = 1 31 32// Which attention kind sits at depth `layer` for `ratio` linear layers per 1 full layer? 33// Every (ratio+1)-th layer is full attention; the rest are linear (KDA). 34func kdasched_kind(layer: i64, ratio: i64) -> i64 { 35 if ratio <= 0 { return KDASCHED_FULL } 36 if ((layer + 1) % (ratio + 1)) == 0 { return KDASCHED_FULL } 37 return KDASCHED_LINEAR 38} 39 40// how many of n_layers still keep a KV cache that GROWS with sequence length 41func kdasched_full_layers(n_layers: i64, ratio: i64) -> i64 { 42 var c: i64 = 0 43 var l: i64 = 0 44 while l < n_layers { 45 if kdasched_kind(l, ratio) == KDASCHED_FULL { c = c + 1 } 46 l = l + 1 47 } 48 return c 49} 50 51// KV-growth reduction in permille vs an all-full-attention stack of the same depth. 52// This is the schedule's whole point, so it is a function and not a comment. 53func kdasched_kv_cut_permille(n_layers: i64, ratio: i64) -> i64 { 54 if n_layers <= 0 { return 0 } 55 let full: i64 = kdasched_full_layers(n_layers, ratio) 56 return ((n_layers - full) * 1000) / n_layers 57}