code wiki / (root) / nx_f32_sampler_test.nx

nx_f32_sampler_test.nx source

↩ module page · 185 lines · 6823 B

1// nx_f32_sampler_test.nx -- smoke for nx_f32_sampler.nx. 2 3import "nx_syscalls.nx" 4import "nx_tier.nx" 5import "nx_prng.nx" 6import "nx_f32.nx" 7import "nx_f32_sampler.nx" 8 9func main() -> i64 { 10 var vi: nx_int = 0 11 while vi < NX_FSP_N_VERDICTS { 12 if nx_fsp_verdict_is_valid(vi) != 1 { return 5 + vi } 13 vi = vi + 1 14 } 15 16 // Logits: [1.0, 2.0, 3.0, 4.0] 17 let logits: *i64 = sys_mmap(4 * 8) as *i64 18 logits[0] = 0x3F800000 19 logits[1] = 0x40000000 20 logits[2] = 0x40400000 21 logits[3] = 0x40800000 22 23 // ===== Argmax ===== 24 let amax: nx_int = nx_f32_sampler_argmax(logits, 4) 25 if amax != 3 { return 10 } 26 27 // Negative logits. 28 let neg_logits: *i64 = sys_mmap(4 * 8) as *i64 29 neg_logits[0] = 0xC0800000 // -4 30 neg_logits[1] = 0xC0400000 // -3 31 neg_logits[2] = 0xC0000000 // -2 32 neg_logits[3] = 0xBF800000 // -1 33 let amax2: nx_int = nx_f32_sampler_argmax(neg_logits, 4) 34 if amax2 != 3 { return 11 } 35 36 // ===== Temperature sample ===== 37 let prng: *i64 = sys_mmap(8) as *i64 38 nx_prng_init(prng, 42 as i64) 39 40 // temp=1.0, inv_temp=1.0 41 let one: i64 = 0x3F800000 42 var ti: nx_int = 0 43 while ti < 20 { 44 let id: nx_int = nx_f32_sampler_sample_temp(logits, 4, one, prng) 45 if id < 0 { return 20 + ti } 46 if id >= 4 { return 50 + ti } 47 ti = ti + 1 48 } 49 50 // High inv_temp (low temperature) -> argmax collapse. inv_temp = 100.0 = 0x42C80000. 51 let inv_temp_100: i64 = 0x42C80000 52 var lt_count: nx_int = 0 53 var t2: nx_int = 0 54 while t2 < 20 { 55 let id: nx_int = nx_f32_sampler_sample_temp(logits, 4, inv_temp_100, prng) 56 if id == 3 { lt_count = lt_count + 1 } 57 t2 = t2 + 1 58 } 59 // With inv_temp=100 the softmax distribution heavily peaks at the argmax. 60 // We expect >= 18/20 hits on id=3 (well above pure-chance 5/20 = 25%). 61 if lt_count < 15 { return 80 } 62 63 // ===== Top-k ===== 64 // top-k=1 with low temp -> deterministic argmax. 65 let id_k1: nx_int = nx_f32_sampler_sample_top_k(logits, 4, 1, one, prng) 66 if id_k1 != 3 { return 90 } 67 68 // top-k=2 with low temp -> id in {2, 3}. 69 var hi: nx_int = 0 70 while hi < 10 { 71 let id: nx_int = nx_f32_sampler_sample_top_k(logits, 4, 2, one, prng) 72 if id != 2 { 73 if id != 3 { return 100 + hi } 74 } 75 hi = hi + 1 76 } 77 78 // top-k >= vocab_size -> behaves like sample_temp. 79 let id_kbig: nx_int = nx_f32_sampler_sample_top_k(logits, 4, 10, one, prng) 80 if id_kbig < 0 { return 120 } 81 if id_kbig >= 4 { return 121 } 82 83 // top-k <= 0 -> falls through to argmax. 84 let id_k0: nx_int = nx_f32_sampler_sample_top_k(logits, 4, 0, one, prng) 85 if id_k0 != 3 { return 130 } 86 87 // ===== Top-p ===== 88 // p_q14 = 0 -> argmax. 89 let id_p0: nx_int = nx_f32_sampler_sample_top_p(logits, 4, 0, one, prng) 90 if id_p0 != 3 { return 140 } 91 92 // p_q14 >= 16384 (= prob >= 1.0) -> no truncation; should sample 93 // from full distribution. Just verify validity. 94 let id_p1: nx_int = nx_f32_sampler_sample_top_p(logits, 4, 16384, one, prng) 95 if id_p1 < 0 { return 150 } 96 if id_p1 >= 4 { return 151 } 97 98 // p_q14 = 4915 (= ~0.3). Logits [1,2,3,4] with temp=1.0 produce probs 99 // ~[0.032, 0.087, 0.237, 0.643]. Cumsum-descending: 0.643 -> stops 100 // at one element (top-1 = id=3, the argmax). Sampling collapses to 3. 101 let id_p_low: nx_int = nx_f32_sampler_sample_top_p(logits, 4, 4915, one, prng) 102 if id_p_low != 3 { return 160 } 103 104 // p_q14 = 13107 (= 0.8). Cumsum hits 0.8 at top-2 (0.643 + 0.237 = 0.880). 105 // Sample should be in {2, 3}. 106 var pp: nx_int = 0 107 while pp < 10 { 108 let id: nx_int = nx_f32_sampler_sample_top_p(logits, 4, 13107, one, prng) 109 if id != 2 { 110 if id != 3 { return 170 + pp } 111 } 112 pp = pp + 1 113 } 114 115 // ===== Repetition penalty ===== 116 // Logits [1, 2, 3, 4]; argmax = 3. Apply penalty=2.0 to recent=[3, 1]: 117 // logits[3] = 4 / 2 = 2.0 118 // logits[1] = 2 / 2 = 1.0 119 // After: logits = [1, 1, 3, 2] -> argmax = 2. 120 let logits_rep: *i64 = sys_mmap(4 * 8) as *i64 121 logits_rep[0] = 0x3F800000 122 logits_rep[1] = 0x40000000 123 logits_rep[2] = 0x40400000 124 logits_rep[3] = 0x40800000 125 let recent: *i64 = sys_mmap(2 * 8) as *i64 126 recent[0] = 3 127 recent[1] = 1 128 let penalty: i64 = 0x40000000 // 2.0 129 nx_f32_sampler_apply_repetition_penalty(logits_rep, 4, recent, 2, penalty) 130 if logits_rep[0] != 0x3F800000 { return 200 } // unchanged 131 if logits_rep[1] != 0x3F800000 { return 201 } // 2.0 / 2 = 1.0 132 if logits_rep[2] != 0x40400000 { return 202 } // unchanged 133 if logits_rep[3] != 0x40000000 { return 203 } // 4.0 / 2 = 2.0 134 let amax_rep: nx_int = nx_f32_sampler_argmax(logits_rep, 4) 135 if amax_rep != 2 { return 210 } // argmax shifted from 3 to 2 136 137 // Negative-logit case: l < 0 -> multiply (more negative -> less likely). 138 let logits_neg: *i64 = sys_mmap(2 * 8) as *i64 139 logits_neg[0] = 0xBF800000 // -1.0 140 logits_neg[1] = 0x3F800000 // 1.0 141 let recent_neg: *i64 = sys_mmap(1 * 8) as *i64 142 recent_neg[0] = 0 143 nx_f32_sampler_apply_repetition_penalty(logits_neg, 2, recent_neg, 1, penalty) 144 if logits_neg[0] != 0xC0000000 { return 220 } // -1.0 * 2 = -2.0 145 if logits_neg[1] != 0x3F800000 { return 221 } // unchanged 146 147 // Out-of-range token id silently skipped. 148 let logits_oor: *i64 = sys_mmap(2 * 8) as *i64 149 logits_oor[0] = 0x3F800000 150 logits_oor[1] = 0x40000000 151 let recent_oor: *i64 = sys_mmap(2 * 8) as *i64 152 recent_oor[0] = 99 153 recent_oor[1] = -1 154 nx_f32_sampler_apply_repetition_penalty(logits_oor, 2, recent_oor, 2, penalty) 155 if logits_oor[0] != 0x3F800000 { return 230 } 156 if logits_oor[1] != 0x40000000 { return 231 } 157 158 // ===== Min-p ===== 159 // Logits [1, 2, 3, 4]; softmax probs ~[0.032, 0.087, 0.237, 0.643] 160 // max_prob ~ 0.643. 161 // min_p=0.5 (q14=8192): threshold = 0.5 * 0.643 = 0.321 162 // Tokens with prob >= 0.321: only id=3 (0.643). k=1, argmax = 3. 163 let id_mp_high: nx_int = nx_f32_sampler_sample_min_p(logits, 4, 8192, one, prng) 164 if id_mp_high != 3 { return 240 } 165 166 // min_p=0.1 (q14=1638): threshold = 0.1 * 0.643 = 0.064 167 // Tokens with prob >= 0.064: ids 1, 2, 3 (0.087, 0.237, 0.643). k=3. 168 var mp: nx_int = 0 169 while mp < 10 { 170 let id: nx_int = nx_f32_sampler_sample_min_p(logits, 4, 1638, one, prng) 171 if id != 1 { 172 if id != 2 { 173 if id != 3 { return 250 + mp } 174 } 175 } 176 mp = mp + 1 177 } 178 179 // min_p=0 -> falls through to plain sample_temp. 180 let id_mp_zero: nx_int = nx_f32_sampler_sample_min_p(logits, 4, 0, one, prng) 181 if id_mp_zero < 0 { return 270 } 182 if id_mp_zero >= 4 { return 271 } 183 184 return 0 185}