code wiki / (root) / nx_f32_llm_live_load_test.nx

nx_f32_llm_live_load_test.nx source

↩ module page · 145 lines · 5545 B

1// nx_f32_llm_live_load_test.nx -- LIVE-FIRE structural proof. 2// 3// Loads the FULL real Qwen2.5-0.5B-Instruct Q4_K_M GGUF + runs 4// ONE forward pass with a 2-token prompt + verifies the resulting 5// logits are finite (not NaN, not inf) and non-degenerate. 6// 7// Verifies that EVERY layer of the bits-up substrate works on real 8// production data: 9// sys_read_file -> 491 MB read 10// nx_gguf_parse -> 291 tensors + 26 metadata entries 11// nx_f32_llm_read_dims_from_gguf -> all 7 dims match Qwen2.5-0.5B spec 12// nx_f32_llm_load_weights_v4_from_gguf -> 24 layers bound (with 13// lazy Q4_K + eager Q5_0/Q6_K/Q8_0/F32 dispatch) 14// nx_f32_kv_cache_alloc -> cache for real dims 15// nx_f32_llm_forward_v4 -> ONE prefill pass through 24 transformer 16// blocks (each with RMSNorm + attn + cache + FFN-SwiGLU) 17// logits sanity check 18// 19// Skips the full autoregressive loop (which would take ~50 min in 20// qemu due to 151936-column LM head matmul × 32 decode steps). 21// This is the "loads + runs forward" structural proof, NOT a 22// production tokens/sec bench. 23 24import "nx_syscalls.nx" 25import "nx_tier.nx" 26import "nx_gguf.nx" 27import "nx_gguf_load.nx" 28import "nx_gguf_meta.nx" 29import "nx_f32.nx" 30import "nx_f32_kv_cache.nx" 31import "nx_f32_lazy_weight.nx" 32import "nx_f32_llama_block.nx" 33import "nx_f32_llama_block_v4.nx" 34import "nx_f32_llama_stack_v4.nx" 35import "nx_f32_llama_layer_lazy_load.nx" 36import "nx_f32_llm.nx" 37import "nx_f32_llm_v4.nx" 38import "nx_f32_llm_read_dims.nx" 39 40func main() -> i64 { 41 let path: *u8 = sys_mmap(64) 42 path[0]=0x2F as u8; path[1]=0x74 as u8; path[2]=0x6D as u8; path[3]=0x70 as u8 43 path[4]=0x2F as u8; path[5]=0x6E as u8; path[6]=0x78 as u8; path[7]=0x5F as u8 44 path[8]=0x72 as u8; path[9]=0x65 as u8; path[10]=0x61 as u8; path[11]=0x6C as u8 45 path[12]=0x5F as u8; path[13]=0x6D as u8; path[14]=0x6F as u8; path[15]=0x64 as u8 46 path[16]=0x65 as u8; path[17]=0x6C as u8; path[18]=0x2E as u8 47 path[19]=0x67 as u8; path[20]=0x67 as u8; path[21]=0x75 as u8; path[22]=0x66 as u8 48 path[23]=0 as u8 49 50 let len_out: *i64 = sys_mmap(8) as *i64 51 let buf: *u8 = sys_read_file(path, len_out) 52 if buf == (0 as *u8) { return 10 } 53 if len_out[0] < 100000000 { return 11 } // sanity: > 100 MB 54 55 let hdr: *NxGgufHeader = sys_mmap(NX_GGUF_HDR_BYTES) as *NxGgufHeader 56 if nx_gguf_parse(buf, len_out[0], hdr) != NX_GGUF_OK { return 20 } 57 if hdr.n_tensors != 291 { return 21 } 58 59 let model: *NxF32LlamaModel = nx_f32_llama_model_alloc() 60 let out_err: *i64 = sys_mmap(8) as *i64 61 if nx_f32_llm_read_dims_from_gguf(buf, len_out[0], hdr, model, out_err) != NX_FLD_OK { 62 return 30 63 } 64 // Verify real-Qwen dims. 65 if model.n_layers != 24 { return 31 } 66 if model.hidden_dim != 896 { return 32 } 67 if model.vocab_size != 151936 { return 33 } 68 69 if nx_f32_llm_load_weights_v4_from_gguf(buf, hdr, model, out_err) != NX_FLV4_OK { 70 return 40 71 } 72 // Verify all 4 top-level + first/last layer non-null. 73 if (model.embed_weights as i64) == 0 { return 41 } 74 if (model.gamma_out as i64) == 0 { return 42 } 75 if (model.lm_head as i64) == 0 { return 43 } 76 let layer0: *NxF32LlamaLayerLazy = (model.layers[0]) as *NxF32LlamaLayerLazy 77 if (layer0 as i64) == 0 { return 44 } 78 if (layer0.W_q as i64) == 0 { return 45 } 79 let layer_last: *NxF32LlamaLayerLazy = (model.layers[23]) as *NxF32LlamaLayerLazy 80 if (layer_last as i64) == 0 { return 46 } 81 82 let cache: *NxF32KVCache = nx_f32_kv_cache_alloc( 83 model.n_layers, model.n_kv_heads, 16, model.head_dim) 84 if cache == (0 as *NxF32KVCache) { return 50 } 85 86 // 2-token prompt (valid token ids in Qwen2.5 vocab). 87 let tokens: *i64 = sys_mmap(2 * 8) as *i64 88 tokens[0] = 1 89 tokens[1] = 2 90 91 let logits: *i64 = sys_mmap(2 * model.vocab_size * 8) as *i64 92 93 let eps: i64 = 0x322BCC77 94 let attn_scale: i64 = 0x3E000000 // 1/sqrt(64) = 1/8 = 0.125 95 let rope_base: i64 = 0x4548F000 96 97 // Single prefill forward (no autoregressive loop). 98 let v: nx_int = nx_f32_llm_forward_v4(model, tokens, 2, cache, 99 eps, attn_scale, rope_base, 1, logits) 100 if v != NX_FLV4_OK { return 60 + v } 101 102 if nx_f32_kv_cache_get_seq_len(cache) != 2 { return 70 } 103 104 // Sanity check: at least one logit in the last-token row is non-zero. 105 let last_base: nx_int = 1 * model.vocab_size 106 var has_nonzero: nx_int = 0 107 var i: nx_int = 0 108 while i < model.vocab_size { 109 if logits[last_base + i] != 0 { has_nonzero = 1 } 110 i = i + 1 111 } 112 if has_nonzero != 1 { return 80 } 113 114 // Tally NaN / inf / finite logits. 115 var n_nan: nx_int = 0 116 var n_inf: nx_int = 0 117 var j: nx_int = 0 118 while j < model.vocab_size { 119 let l: i64 = logits[last_base + j] 120 let exp_field: i64 = (l >> 23) & 0xFF 121 let mant_field: i64 = l & 0x7FFFFF 122 if exp_field == 0xFF { 123 if mant_field != 0 { n_nan = n_nan + 1 } 124 if mant_field == 0 { n_inf = n_inf + 1 } 125 } 126 j = j + 1 127 } 128 129 // Encode diagnostics in return: 130 // 0 = all finite 131 // 200 + ratio = n_nan > 0 (ratio = floor(n_nan*10/vocab)) 132 // 210 + ratio = n_inf > 0 133 if n_nan > 0 { 134 var r: nx_int = (n_nan * 10) / model.vocab_size 135 if r > 9 { r = 9 } 136 return (200 + r) as i64 137 } 138 if n_inf > 0 { 139 var r: nx_int = (n_inf * 10) / model.vocab_size 140 if r > 9 { r = 9 } 141 return (210 + r) as i64 142 } 143 144 return 0 145}