code wiki / (root) / nx_gguf_load_model_test.nx

nx_gguf_load_model_test.nx source

↩ module page · 185 lines · 7488 B

1// nx_gguf_load_model_test.nx -- smoke for nx_gguf_load_model.nx. 2// 3// Builds two synthetic GGUFs: 4// A) Full model (3 tensors): token_embd + output_norm + output 5// B) Tied-embedding model (2 tensors): token_embd + output_norm 6// (no output.weight; caller expected to reuse token_embd) 7// 8// Verifies: 9// - Bundle struct populated correctly when all 3 tensors present 10// - is_output_tied flag and null output_weight when output.weight 11// is missing 12// - Verdict-range gate 13 14import "nx_syscalls.nx" 15import "nx_tier.nx" 16import "nx_le.nx" 17import "nx_tensor.nx" 18import "nx_gguf.nx" 19import "nx_gguf_load.nx" 20import "nx_gguf_load_model.nx" 21 22// Helper: write a tensor_info entry at a given offset. 23// Returns the offset AFTER this entry. 24func _write_ti(buf: *u8, off: i64, 25 name: *u8, name_len: i64, 26 n_dims: i64, dim_0: i64, dim_1: i64, 27 ggml_type: i64, data_offset: i64) -> i64 { 28 nx_le_write_u64(buf, off, name_len) 29 var o: i64 = off + 8 30 var i: i64 = 0 31 while i < name_len { buf[o + i] = name[i]; i = i + 1 } 32 o = o + name_len 33 nx_le_write_u32(buf, o, n_dims); o = o + 4 34 nx_le_write_u64(buf, o, dim_0); o = o + 8 35 if n_dims >= 2 { nx_le_write_u64(buf, o, dim_1); o = o + 8 } 36 nx_le_write_u32(buf, o, ggml_type); o = o + 4 37 nx_le_write_u64(buf, o, data_offset); o = o + 8 38 return o 39} 40 41func main() -> i64 { 42 // ----- Verdict gate ----- 43 var vi: nx_int = 0 44 while vi < NX_GML_N_VERDICTS { 45 if nx_gml_verdict_is_valid(vi) != 1 { return 5 + vi } 46 vi = vi + 1 47 } 48 49 // ----- A) Full model: 3 tensors ----- 50 let buf_a: *u8 = sys_mmap(2048) 51 buf_a[0]=0x47; buf_a[1]=0x47; buf_a[2]=0x55; buf_a[3]=0x46 52 buf_a[4]=3 53 nx_le_write_u64(buf_a, 8, 3) 54 nx_le_write_u64(buf_a, 16, 0) 55 56 // Tensor names 57 let n_te: *u8 = sys_mmap(17) 58 n_te[0]=0x74; n_te[1]=0x6f; n_te[2]=0x6b; n_te[3]=0x65 59 n_te[4]=0x6e; n_te[5]=0x5f; n_te[6]=0x65; n_te[7]=0x6d 60 n_te[8]=0x62; n_te[9]=0x64; n_te[10]=0x2e; n_te[11]=0x77 61 n_te[12]=0x65; n_te[13]=0x69; n_te[14]=0x67; n_te[15]=0x68 62 n_te[16]=0x74 63 64 let n_on: *u8 = sys_mmap(18) 65 n_on[0]=0x6f; n_on[1]=0x75; n_on[2]=0x74; n_on[3]=0x70 66 n_on[4]=0x75; n_on[5]=0x74; n_on[6]=0x5f; n_on[7]=0x6e 67 n_on[8]=0x6f; n_on[9]=0x72; n_on[10]=0x6d; n_on[11]=0x2e 68 n_on[12]=0x77; n_on[13]=0x65; n_on[14]=0x69; n_on[15]=0x67 69 n_on[16]=0x68; n_on[17]=0x74 70 71 let n_ow: *u8 = sys_mmap(13) 72 n_ow[0]=0x6f; n_ow[1]=0x75; n_ow[2]=0x74; n_ow[3]=0x70 73 n_ow[4]=0x75; n_ow[5]=0x74; n_ow[6]=0x2e; n_ow[7]=0x77 74 n_ow[8]=0x65; n_ow[9]=0x69; n_ow[10]=0x67; n_ow[11]=0x68 75 n_ow[12]=0x74 76 77 // ti[0] token_embd F32 [4,2] (vocab=4, hidden=2) data_off rel = 0 78 var pa: i64 = 24 79 pa = _write_ti(buf_a, pa, n_te, 17, 2, 4, 2, NX_GGML_TYPE_F32, 0) 80 // ti[1] output_norm F32 [2] data_off rel = 32 (4*2*4=32) 81 pa = _write_ti(buf_a, pa, n_on, 18, 1, 2, 1, NX_GGML_TYPE_F32, 32) 82 // ti[2] output F32 [2,4] data_off rel = 40 (32+2*4=40) 83 pa = _write_ti(buf_a, pa, n_ow, 13, 2, 2, 4, NX_GGML_TYPE_F32, 40) 84 85 // data_off = align_up(pa, 32). 86 let data_off_a: i64 = (pa + 31) / 32 * 32 87 88 // token_embd [4,2] = 8 F32 values: 0.5, 1.0, 1.5, 2.0, -0.5, -1.0, -1.5, -2.0 89 nx_le_write_u32(buf_a, data_off_a + 0, 0x3F000000) // 0.5 90 nx_le_write_u32(buf_a, data_off_a + 4, 0x3F800000) // 1.0 91 nx_le_write_u32(buf_a, data_off_a + 8, 0x3FC00000) // 1.5 92 nx_le_write_u32(buf_a, data_off_a + 12, 0x40000000) // 2.0 93 nx_le_write_u32(buf_a, data_off_a + 16, 0xBF000000) // -0.5 94 nx_le_write_u32(buf_a, data_off_a + 20, 0xBF800000) // -1.0 95 nx_le_write_u32(buf_a, data_off_a + 24, 0xBFC00000) // -1.5 96 nx_le_write_u32(buf_a, data_off_a + 28, 0xC0000000) // -2.0 97 98 // output_norm [2] = 1.0, 1.0 99 nx_le_write_u32(buf_a, data_off_a + 32, 0x3F800000) 100 nx_le_write_u32(buf_a, data_off_a + 36, 0x3F800000) 101 102 // output [2,4] = 8 F32 values: 1, 2, 3, 4, 5, 6, 7, 8 (just nonzero markers) 103 nx_le_write_u32(buf_a, data_off_a + 40, 0x3F800000) // 1.0 104 nx_le_write_u32(buf_a, data_off_a + 44, 0x40000000) // 2.0 105 nx_le_write_u32(buf_a, data_off_a + 48, 0x40400000) // 3.0 106 nx_le_write_u32(buf_a, data_off_a + 52, 0x40800000) // 4.0 107 nx_le_write_u32(buf_a, data_off_a + 56, 0x40A00000) // 5.0 108 nx_le_write_u32(buf_a, data_off_a + 60, 0x40C00000) // 6.0 109 nx_le_write_u32(buf_a, data_off_a + 64, 0x40E00000) // 7.0 110 nx_le_write_u32(buf_a, data_off_a + 68, 0x41000000) // 8.0 111 112 let hdr_a: *NxGgufHeader = sys_mmap(NX_GGUF_HDR_BYTES) as *NxGgufHeader 113 let vp_a: nx_int = nx_gguf_parse(buf_a, 2048, hdr_a) 114 if vp_a != NX_GGUF_OK { return 20 + vp_a } 115 if hdr_a.n_tensors != 3 { return 30 } 116 117 let bundle_a: *NxGgufModelWeights = sys_mmap(NX_GML_BUNDLE_BYTES) as *NxGgufModelWeights 118 let err: *i64 = sys_mmap(8) as *i64 119 err[0] = 0 120 let v_a: nx_int = nx_gguf_load_model_weights(buf_a, hdr_a, bundle_a, err) 121 if v_a != NX_GML_OK { return 40 + v_a } 122 if err[0] != NX_GML_OK { return 50 } 123 if bundle_a.is_output_tied != 0 { return 51 } 124 if bundle_a.token_embd.numel != 8 { return 52 } 125 if bundle_a.output_weight.numel != 8 { return 53 } 126 127 let tep: *i64 = bundle_a.token_embd.storage as *i64 128 if tep[0] != 512 { return 60 } // 0.5 -> Q10 512 129 if tep[3] != 2048 { return 61 } // 2.0 -> Q10 2048 130 if tep[4] != (0 - 512) { return 62 } 131 if tep[7] != (0 - 2048) { return 63 } 132 133 if bundle_a.output_norm_gamma[0] != 1024 { return 70 } 134 if bundle_a.output_norm_gamma[1] != 1024 { return 71 } 135 136 let owp: *i64 = bundle_a.output_weight.storage as *i64 137 if owp[0] != 1024 { return 80 } // 1.0 138 if owp[7] != 8192 { return 81 } // 8.0 -> 8192 139 140 // ----- B) Tied-embedding: only 2 tensors (no output.weight) ----- 141 let buf_b: *u8 = sys_mmap(2048) 142 buf_b[0]=0x47; buf_b[1]=0x47; buf_b[2]=0x55; buf_b[3]=0x46 143 buf_b[4]=3 144 nx_le_write_u64(buf_b, 8, 2) // 2 tensors 145 nx_le_write_u64(buf_b, 16, 0) 146 147 var pb: i64 = 24 148 pb = _write_ti(buf_b, pb, n_te, 17, 2, 4, 2, NX_GGML_TYPE_F32, 0) 149 pb = _write_ti(buf_b, pb, n_on, 18, 1, 2, 1, NX_GGML_TYPE_F32, 32) 150 let data_off_b: i64 = (pb + 31) / 32 * 32 151 152 // Same data layout for token_embd + output_norm 153 var bi: nx_int = 0 154 while bi < 8 { 155 // Re-use the F32 patterns by copying from buf_a data section 156 var bj: nx_int = 0 157 while bj < 4 { 158 buf_b[data_off_b + bi * 4 + bj] = buf_a[data_off_a + bi * 4 + bj] 159 bj = bj + 1 160 } 161 bi = bi + 1 162 } 163 // output_norm bytes 164 var bk: nx_int = 0 165 while bk < 8 { 166 buf_b[data_off_b + 32 + bk] = buf_a[data_off_a + 32 + bk] 167 bk = bk + 1 168 } 169 170 let hdr_b: *NxGgufHeader = sys_mmap(NX_GGUF_HDR_BYTES) as *NxGgufHeader 171 let vp_b: nx_int = nx_gguf_parse(buf_b, 2048, hdr_b) 172 if vp_b != NX_GGUF_OK { return 90 + vp_b } 173 if hdr_b.n_tensors != 2 { return 100 } 174 175 let bundle_b: *NxGgufModelWeights = sys_mmap(NX_GML_BUNDLE_BYTES) as *NxGgufModelWeights 176 err[0] = 0 177 let v_b: nx_int = nx_gguf_load_model_weights(buf_b, hdr_b, bundle_b, err) 178 if v_b != NX_GML_OK { return 110 + v_b } 179 if err[0] != NX_GML_OK { return 120 } 180 if bundle_b.is_output_tied != 1 { return 121 } 181 if bundle_b.output_weight != (0 as *NxTensor) { return 122 } 182 if bundle_b.token_embd.numel != 8 { return 123 } 183 184 return 0 185}