char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
a2878d30d
char/aliceai-t5-moe
1#include "common.h" 2 3constant short FC_gated_delta_net_ne20 [[function_constant(FC_GATED_DELTA_NET + 0)]]; 4constant short FC_gated_delta_net_ne30 [[function_constant(FC_GATED_DELTA_NET + 1)]]; 5constant short FC_gated_delta_net_K [[function_constant(FC_GATED_DELTA_NET + 2)]]; 6 7#if 1 8template<short NSG> 9kernel void kernel_gated_delta_net_impl( 10 constant ggml_metal_kargs_gated_delta_net & args, 11 device const char * q, 12 device const char * k, 13 device const char * v, 14 device const char * g, 15 device const char * b, 16 device const char * s, 17 device char * dst, 18 device char * dst_fuse, 19 uint3 tgpig[[threadgroup_position_in_grid]], 20 uint3 tpitg[[thread_position_in_threadgroup]], 21 uint3 ntg[[threads_per_threadgroup]]) { 22#define S_v FC_gated_delta_net_ne20 23#define G FC_gated_delta_net_ne30 24#define K FC_gated_delta_net_K 25 26 const uint tx = tpitg.x; 27 const uint ty = tpitg.y; 28 29 const uint i23 = tgpig.z; // B (n_seqs) 30 const uint i21 = tgpig.y; // H (head) 31 const uint i20 = tgpig.x*NSG + ty; // row within S_v 32 33 const uint i01 = i21 % args.ne01; 34 const uint i11 = i21 % args.ne11; 35 36 const float scale = 1.0f / sqrt((float)S_v); 37 38 // input state layout [S_v, S_v, H, n_seqs] (s0 only): per-seq stride is H*D. 39 // state is stored transposed: M[i20][is] = S[is][i20], so row i20 is contiguous 40 const uint state_in_base = (i23*args.ne21 + i21)*S_v*S_v + i20*S_v; 41 device const float * s_ptr = (device const float *) (s) + state_in_base; 42 43 float ls[NSG]; 44 45 FOR_UNROLL (short j = 0; j < NSG; j++) { 46 const short is = tx*NSG + j; 47 ls[j] = s_ptr[is]; 48 } 49 50 device float * dst_attn = (device float *) (dst) + (i23*args.ne22*args.ne21 + i21)*S_v + i20; 51 52 device const float * q_ptr = (device const float *) (q + i23*args.nb03 + i01*args.nb01); 53 device const float * k_ptr = (device const float *) (k + i23*args.nb13 + i11*args.nb11); 54 device const float * v_ptr = (device const float *) (v + i23*args.nb23 + i21*args.nb21); 55 56 device const float * b_ptr = (device const float *) (b) + (i23*args.ne22*args.ne21 + i21); 57 device const float * g_ptr = (device const float *) (g) + (i23*args.ne22*args.ne21 + i21)*G; 58 59 // snapshot slot mapping: slot 0 = most recent state, slot s = s tokens back. 60 // When n_tokens < K, only slots 0..n_tokens-1 are written; older slots are caller-owned. 61 62 // output state base offset: after attention scores 63 const uint attn_size = args.ne22 * args.ne21 * S_v * args.ne23; 64 // output state per-slot size: S_v * S_v * H * n_seqs 65 const uint state_size_per_snap = S_v * S_v * args.ne21 * args.ne23; 66 // per-(seq,head) offset within a slot 67 const uint state_out_base = (i23*args.ne21 + i21)*S_v*S_v + i20*S_v; 68 69 // when fused with the cache cpy, write the snapshots straight into the cache buffer using 70 // the slot stride; otherwise append them after the attn scores (nb_out == 0) 71 const bool fused = args.nb_out > 0; 72 const device float * state_out = fused ? (device float *)dst_fuse : (device float *)dst + attn_size; 73 const uint slot_stride = fused ? (uint)args.nb_out : state_size_per_snap; 74 75 for (short t = 0; t < args.ne22; t++) { 76 float s_k = 0.0f; 77 78 if (G == 1) { 79 const float g_exp = exp(g_ptr[0]); 80 81 FOR_UNROLL (short j = 0; j < NSG; j++) { 82 const short is = tx*NSG + j; 83 ls[j] *= g_exp; 84 85 s_k += ls[j]*k_ptr[is]; 86 } 87 } else { 88 // KDA 89 FOR_UNROLL (short j = 0; j < NSG; j++) { 90 const short is = tx*NSG + j; 91 ls[j] *= exp(g_ptr[is]); 92 93 s_k += ls[j]*k_ptr[is]; 94 } 95 } 96 97 s_k = simd_sum(s_k); 98 99 const float d = (v_ptr[i20] - s_k)*b_ptr[0]; 100 101 float y = 0.0f; 102 103 FOR_UNROLL (short j = 0; j < NSG; j++) { 104 const short is = tx*NSG + j; 105 ls[j] += k_ptr[is]*d; 106 107 y += ls[j]*q_ptr[is]; 108 } 109 110 y = simd_sum(y); 111 112 if (tx == 0) { 113 dst_attn[t*args.ne21*S_v] = y*scale; 114 } 115 116 q_ptr += args.ns02; 117 k_ptr += args.ns12; 118 v_ptr += args.ns22; 119 120 b_ptr += args.ne21; 121 g_ptr += args.ne21*G; 122 123 if (K > 1) { 124 const int target_slot = (int)args.ne22 - 1 - (int)t; 125 if (target_slot >= 0 && target_slot < (int)K) { 126 device float * dst_state = (device float *)state_out + (uint)target_slot * slot_stride + state_out_base; 127 FOR_UNROLL (short j = 0; j < NSG; j++) { 128 const short is = tx*NSG + j; 129 dst_state[is] = ls[j]; 130 } 131 } 132 } 133 } 134 135 if (K == 1) { 136 device float * dst_state = (device float *)state_out + state_out_base; 137 FOR_UNROLL (short j = 0; j < NSG; j++) { 138 const short is = tx*NSG + j; 139 dst_state[is] = ls[j]; 140 } 141 } 142 143#undef S_v 144#undef G 145#undef K 146} 147 148typedef decltype(kernel_gated_delta_net_impl<4>) kernel_gated_delta_net_t; 149 150template [[host_name("kernel_gated_delta_net_f32_1")]] kernel kernel_gated_delta_net_t kernel_gated_delta_net_impl<1>; 151template [[host_name("kernel_gated_delta_net_f32_2")]] kernel kernel_gated_delta_net_t kernel_gated_delta_net_impl<2>; 152template [[host_name("kernel_gated_delta_net_f32_4")]] kernel kernel_gated_delta_net_t kernel_gated_delta_net_impl<4>; 153 154#else 155// a simplified version of the above 156// no performance improvement, so keep the above version for now 157 158template<typename T, short NSG> 159kernel void kernel_gated_delta_net_impl( 160 constant ggml_metal_kargs_gated_delta_net & args, 161 device const char * q, 162 device const char * k, 163 device const char * v, 164 device const char * g, 165 device const char * b, 166 device const char * s, 167 device char * dst, 168 device char * dst_fuse, 169 uint3 tgpig[[threadgroup_position_in_grid]], 170 uint3 tpitg[[thread_position_in_threadgroup]], 171 uint3 ntg[[threads_per_threadgroup]]) { 172#define S_v FC_gated_delta_net_ne20 173#define G FC_gated_delta_net_ne30 174 175 const uint tx = tpitg.x; 176 const uint ty = tpitg.y; 177 178 const uint i23 = tgpig.z; // B 179 const uint i21 = tgpig.y; // H 180 const uint i20 = tgpig.x*NSG + ty; 181 182 const uint i01 = i21 % args.ne01; 183 const uint i11 = i21 % args.ne11; 184 185 const float scale = 1.0f / sqrt((float)S_v); 186 187 device const float * s_ptr = (device const float *) (s) + (i23*args.ne21 + i21)*S_v*S_v + i20; 188 189 float lsf[NSG]; 190 191 FOR_UNROLL (short j = 0; j < NSG; j++) { 192 const short is = tx*NSG + j; 193 lsf[j] = s_ptr[is*S_v]; 194 } 195 196 thread T * ls = (thread T *) (lsf); 197 198 device float * dst_attn = (device float *) (dst) + (i23*args.ne22*args.ne21 + i21)*S_v + i20; 199 200 device const float * q_ptr = (device const float *) (q + i23*args.nb03 + i01*args.nb01); 201 device const float * k_ptr = (device const float *) (k + i23*args.nb13 + i11*args.nb11); 202 device const float * v_ptr = (device const float *) (v + i23*args.nb23 + i21*args.nb21); 203 204 device const float * b_ptr = (device const float *) (b) + (i23*args.ne22*args.ne21 + i21); 205 device const float * g_ptr = (device const float *) (g) + (i23*args.ne22*args.ne21 + i21)*G; 206 207 for (short t = 0; t < args.ne22; t++) { 208 device const T * qt_ptr = (device const T *) (q_ptr); 209 device const T * kt_ptr = (device const T *) (k_ptr); 210 device const T * gt_ptr = (device const T *) (g_ptr); 211 212 if (G == 1) { 213 *ls *= exp(g_ptr[0]); 214 } else { 215 // KDA 216 *ls *= exp(gt_ptr[tx]); 217 } 218 219 const float s_k = simd_sum(dot(*ls, kt_ptr[tx])); 220 221 const float d = (v_ptr[i20] - s_k)*b_ptr[0]; 222 223 *ls += kt_ptr[tx]*d; 224 225 const float y = simd_sum(dot(*ls, qt_ptr[tx])); 226 227 if (tx == 0) { 228 *dst_attn = y*scale; 229 } 230 231 q_ptr += args.ns02; 232 k_ptr += args.ns12; 233 v_ptr += args.ns22; 234 235 b_ptr += args.ne21; 236 g_ptr += args.ne21*G; 237 238 dst_attn += args.ne21*S_v; 239 } 240 241 // when fused with the cache cpy, write the snapshots straight into the cache buffer using 242 // the slot stride; otherwise append them after the attn scores (nb_out == 0) 243 const bool fused = args.nb_out > 0; 244 const device float * state_out = fused ? (device float *)dst_fuse : (device float *)dst + args.ne23*args.ne22*args.ne21*S_v; 245 const uint slot_stride = fused ? (uint)args.nb_out : S_v*S_v; 246 247 device float * dst_state = (device float *)state_out + (i23*args.ne21 + i21)*slot_stride + i20; 248 device T * dstt_state = (device T *) (dst_state); 249 250 FOR_UNROLL (short j = 0; j < NSG; j++) { 251 const short is = tx*NSG + j; 252 dst_state[is*S_v] = lsf[j]; 253 } 254 255#undef S_v 256#undef G 257} 258 259typedef decltype(kernel_gated_delta_net_impl<float4, 4>) kernel_gated_delta_net_t; 260 261template [[host_name("kernel_gated_delta_net_f32_1")]] kernel kernel_gated_delta_net_t kernel_gated_delta_net_impl<float, 1>; 262template [[host_name("kernel_gated_delta_net_f32_2")]] kernel kernel_gated_delta_net_t kernel_gated_delta_net_impl<float2, 2>; 263template [[host_name("kernel_gated_delta_net_f32_4")]] kernel kernel_gated_delta_net_t kernel_gated_delta_net_impl<float4, 4>; 264#endif