char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

YiChen Lvmetal: per-op source split + parallel compile (#26561)b615f5b4b

char/aliceai-t5-moe
13.6 KiB333 linesraw
1#include "common.h"
2
3constant bool FC_rope_is_imrope [[function_constant(FC_ROPE + 0)]];
4constant bool FC_rope_is_back   [[function_constant(FC_ROPE + 1)]];
5
6static float rope_yarn_ramp(const float low, const float high, const int i0) {
7    const float y = (i0 / 2 - low) / max(0.001f, high - low);
8    return 1.0f - min(1.0f, max(0.0f, y));
9}
10
11// YaRN algorithm based on LlamaYaRNScaledRotaryEmbedding.py from https://github.com/jquesnelle/yarn
12// MIT licensed. Copyright (c) 2023 Jeffrey Quesnelle and Bowen Peng.
13static void rope_yarn(
14    float theta_extrap, float freq_scale, float corr_dims[2], int i0, float ext_factor, float mscale,
15    thread float * cos_theta, thread float * sin_theta) {
16    // Get n-d rotational scaling corrected for extrapolation
17    float theta_interp = freq_scale * theta_extrap;
18    float theta = theta_interp;
19    if (ext_factor != 0.0f) {
20        float ramp_mix = rope_yarn_ramp(corr_dims[0], corr_dims[1], i0) * ext_factor;
21        theta = theta_interp * (1 - ramp_mix) + theta_extrap * ramp_mix;
22
23        // Get n-d magnitude scaling corrected for interpolation
24        mscale *= 1.0f + 0.1f * log(1.0f / freq_scale);
25    }
26    *cos_theta = cos(theta) * mscale;
27    *sin_theta = sin(theta) * mscale;
28    if (FC_rope_is_back) {
29        *sin_theta *= -1.0f;
30    }
31}
32
33// Apparently solving `n_rot = 2pi * x * base^((2 * max_pos_emb) / n_dims)` for x, we get
34// `corr_fac(n_rot) = n_dims * log(max_pos_emb / (n_rot * 2pi)) / (2 * log(base))`
35static float rope_yarn_corr_factor(int n_dims, int n_ctx_orig, float n_rot, float base) {
36    return n_dims * log(n_ctx_orig / (n_rot * 2 * M_PI_F)) / (2 * log(base));
37}
38
39static void rope_yarn_corr_dims(
40    int n_dims, int n_ctx_orig, float freq_base, float beta_fast, float beta_slow, float dims[2]
41) {
42    // start and end correction dims
43    dims[0] = max(0.0f,         floor(rope_yarn_corr_factor(n_dims, n_ctx_orig, beta_fast, freq_base)));
44    dims[1] = min(n_dims - 1.0f, ceil(rope_yarn_corr_factor(n_dims, n_ctx_orig, beta_slow, freq_base)));
45}
46
47template<typename T>
48kernel void kernel_rope_norm(
49        constant ggml_metal_kargs_rope & args,
50        device const char * src0,
51        device const char * src1,
52        device const char * src2,
53        device       char * dst,
54        ushort  tiitg[[thread_index_in_threadgroup]],
55        ushort3 tptg [[threads_per_threadgroup]],
56        uint3   tgpig[[threadgroup_position_in_grid]]) {
57    const int i3 = tgpig[2];
58    const int i2 = tgpig[1];
59    const int i1 = tgpig[0];
60
61    float corr_dims[2];
62    rope_yarn_corr_dims(args.n_dims, args.n_ctx_orig, args.freq_base, args.beta_fast, args.beta_slow, corr_dims);
63
64    device const int32_t * pos = (device const int32_t *) src1;
65
66    const float theta_base = (float) pos[i2];
67    const float inv_ndims = -1.f/args.n_dims;
68
69    float cos_theta;
70    float sin_theta;
71
72    for (int i0 = 2*tiitg; i0 < args.ne0; i0 += 2*tptg.x) {
73        if (i0 >= args.n_offs && i0 < args.n_offs + args.n_dims) {
74            const int iw = i0 - args.n_offs; // relative idx
75            const int ic = iw/2;
76
77            const float theta = theta_base * pow(args.freq_base, inv_ndims*iw);
78
79            const float freq_factor = args.src2 ? ((device const float *) src2)[ic] : 1.0f;
80
81            rope_yarn(theta/freq_factor, args.freq_scale, corr_dims, iw, args.ext_factor, args.attn_factor, &cos_theta, &sin_theta);
82
83            device const T * const src = (device T *)(src0 + i3*args.nb03 + i2*args.nb02 + i1*args.nb01 + i0*args.nb00);
84            device       T * dst_data  = (device T *)( dst + i3*args.nb3  + i2*args.nb2  + i1*args.nb1  + i0*args.nb0);
85
86            const float x0 = src[0];
87            const float x1 = src[1];
88
89            dst_data[0] = x0*cos_theta - x1*sin_theta;
90            dst_data[1] = x0*sin_theta + x1*cos_theta;
91        } else {
92            if (args.inplace) {
93                continue;
94            }
95
96            device const T * const src = (device T *)(src0 + i3*args.nb03 + i2*args.nb02 + i1*args.nb01 + i0*args.nb00);
97            device       T * dst_data  = (device T *)( dst + i3*args.nb3  + i2*args.nb2  + i1*args.nb1  + i0*args.nb0);
98
99            dst_data[0] = src[0];
100            dst_data[1] = src[1];
101        }
102    }
103}
104
105template<typename T>
106kernel void kernel_rope_neox(
107        constant ggml_metal_kargs_rope & args,
108        device const char * src0,
109        device const char * src1,
110        device const char * src2,
111        device       char * dst,
112        ushort  tiitg[[thread_index_in_threadgroup]],
113        ushort3 tptg [[threads_per_threadgroup]],
114        uint3   tgpig[[threadgroup_position_in_grid]]) {
115    const int i3 = tgpig[2];
116    const int i2 = tgpig[1];
117    const int i1 = tgpig[0];
118
119    float corr_dims[2];
120    rope_yarn_corr_dims(args.n_dims, args.n_ctx_orig, args.freq_base, args.beta_fast, args.beta_slow, corr_dims);
121
122    device const int32_t * pos = (device const int32_t *) src1;
123
124    const float theta_base = (float) pos[i2];
125    const float inv_ndims = -1.f/args.n_dims;
126
127    float cos_theta;
128    float sin_theta;
129
130    for (int i0 = 2*tiitg; i0 < args.ne0; i0 += 2*tptg.x) {
131        if (i0 >= args.n_offs && i0 < args.n_offs + args.n_dims) {
132            const int iw = i0 - args.n_offs; // relative idx
133            const int ic = iw/2;
134
135            const float theta = theta_base * pow(args.freq_base, inv_ndims*iw);
136
137            const float freq_factor = args.src2 ? ((device const float *) src2)[ic] : 1.0f;
138
139            rope_yarn(theta/freq_factor, args.freq_scale, corr_dims, iw, args.ext_factor, args.attn_factor, &cos_theta, &sin_theta);
140
141            device const T * const src = (device T *)(src0 + i3*args.nb03 + i2*args.nb02 + i1*args.nb01 + (args.n_offs + ic)*args.nb00);
142            device       T * dst_data  = (device T *)( dst + i3*args.nb3  + i2*args.nb2  + i1*args.nb1  + (args.n_offs + ic)*args.nb0);
143
144            const float x0 = src[0];
145            const float x1 = src[args.n_dims/2];
146
147            dst_data[0]             = x0*cos_theta - x1*sin_theta;
148            dst_data[args.n_dims/2] = x0*sin_theta + x1*cos_theta;
149        } else {
150            if (args.inplace) {
151                continue;
152            }
153
154            device const T * const src = (device T *)(src0 + i3*args.nb03 + i2*args.nb02 + i1*args.nb01 + i0*args.nb00);
155            device       T * dst_data  = (device T *)( dst + i3*args.nb3  + i2*args.nb2  + i1*args.nb1  + i0*args.nb0);
156
157            dst_data[0] = src[0];
158            dst_data[1] = src[1];
159        }
160    }
161}
162
163template<typename T>
164kernel void kernel_rope_multi(
165        constant ggml_metal_kargs_rope & args,
166        device const char * src0,
167        device const char * src1,
168        device const char * src2,
169        device       char * dst,
170        ushort  tiitg[[thread_index_in_threadgroup]],
171        ushort3 tptg [[threads_per_threadgroup]],
172        uint3   tgpig[[threadgroup_position_in_grid]]) {
173    const int i3 = tgpig[2];
174    const int i2 = tgpig[1];
175    const int i1 = tgpig[0];
176
177    float corr_dims[2];
178    rope_yarn_corr_dims(args.n_dims, args.n_ctx_orig, args.freq_base, args.beta_fast, args.beta_slow, corr_dims);
179
180    device const int32_t * pos = (device const int32_t *) src1;
181
182    const float inv_ndims = -1.f/args.n_dims;
183
184    float cos_theta;
185    float sin_theta;
186
187    for (int i0 = 2*tiitg; i0 < args.ne0; i0 += 2*tptg.x) {
188        if (i0 >= args.n_offs && i0 < args.n_offs + args.n_dims) {
189            const int iw = i0 - args.n_offs; // relative idx
190            const int ic = iw/2;
191
192            // mrope theta calculations
193            // note: the rest is the same as kernel_rope_neox
194            const int sect_dims = args.sect_0 + args.sect_1 + args.sect_2 + args.sect_3;
195            const int sec_w01   = args.sect_0 + args.sect_1;               // end of section 1
196            const int sec_w012  = args.sect_0 + args.sect_1 + args.sect_2; // end of section 2
197            const int sector    = ic % sect_dims;
198
199            float theta_base;
200            if (FC_rope_is_imrope) {
201                if (sector % 3 == 1 && sector < 3 * args.sect_1) { // h
202                    theta_base = (float) pos[i2 + args.ne02 * 1];
203                } else if (sector % 3 == 2 && sector < 3 * args.sect_2) { // w
204                    theta_base = (float) pos[i2 + args.ne02 * 2];
205                } else if (sector % 3 == 0 && sector < 3 * args.sect_0) { // t
206                    theta_base = (float) pos[i2 + args.ne02 * 0];
207                } else { // e
208                    theta_base = (float) pos[i2 + args.ne02 * 3];
209                }
210            } else {
211                if (sector < args.sect_0) {
212                    theta_base = (float) pos[i2];
213                } else if (sector < sec_w01) {
214                    theta_base = (float) pos[i2 + args.ne02 * 1];
215                } else if (sector < sec_w012) {
216                    theta_base = (float) pos[i2 + args.ne02 * 2];
217                } else {
218                    theta_base = (float) pos[i2 + args.ne02 * 3];
219                }
220            }
221            // end of mrope
222
223            const float theta = theta_base * pow(args.freq_base, inv_ndims*iw);
224
225            const float freq_factor = args.src2 ? ((device const float *) src2)[ic] : 1.0f;
226
227            rope_yarn(theta/freq_factor, args.freq_scale, corr_dims, iw, args.ext_factor, args.attn_factor, &cos_theta, &sin_theta);
228
229            device const T * const src = (device T *)(src0 + i3*args.nb03 + i2*args.nb02 + i1*args.nb01 + (args.n_offs + ic)*args.nb00);
230            device       T * dst_data  = (device T *)( dst + i3*args.nb3  + i2*args.nb2  + i1*args.nb1  + (args.n_offs + ic)*args.nb0);
231
232            const float x0 = src[0];
233            const float x1 = src[args.n_dims/2];
234
235            dst_data[0]             = x0*cos_theta - x1*sin_theta;
236            dst_data[args.n_dims/2] = x0*sin_theta + x1*cos_theta;
237        } else {
238            if (args.inplace) {
239                continue;
240            }
241
242            device const T * const src = (device T *)(src0 + i3*args.nb03 + i2*args.nb02 + i1*args.nb01 + i0*args.nb00);
243            device       T * dst_data  = (device T *)( dst + i3*args.nb3  + i2*args.nb2  + i1*args.nb1  + i0*args.nb0);
244
245            dst_data[0] = src[0];
246            dst_data[1] = src[1];
247        }
248    }
249}
250
251template<typename T>
252kernel void kernel_rope_vision(
253        constant ggml_metal_kargs_rope & args,
254        device const char * src0,
255        device const char * src1,
256        device const char * src2,
257        device       char * dst,
258        ushort  tiitg[[thread_index_in_threadgroup]],
259        ushort3 tptg [[threads_per_threadgroup]],
260        uint3   tgpig[[threadgroup_position_in_grid]]) {
261    const int i3 = tgpig[2];
262    const int i2 = tgpig[1];
263    const int i1 = tgpig[0];
264
265    float corr_dims[2];
266    rope_yarn_corr_dims(args.n_dims, args.n_ctx_orig, args.freq_base, args.beta_fast, args.beta_slow, corr_dims);
267
268    device const int32_t * pos = (device const int32_t *) src1;
269
270    const float inv_ndims = -1.f/args.n_dims;
271
272    float cos_theta;
273    float sin_theta;
274
275    for (int i0 = 2*tiitg; i0 < args.ne0; i0 += 2*tptg.x) {
276        if (i0 < 2*args.n_dims) { // different from kernel_rope_multi
277            const int ic = i0/2;
278
279            // mrope theta calculations (only support 2 dimensions)
280            const int sect_dims = args.sect_0 + args.sect_1;
281            const int sector    = ic % sect_dims;
282
283            float p;
284            float theta_base;
285            if (sector < args.sect_1) {
286                p = (float) sector;
287                theta_base = (float) pos[i2];
288            } else {
289                p = (float) sector - args.sect_0;
290                theta_base = (float) pos[i2 + args.ne02];
291            }
292
293            const float theta = theta_base * pow(args.freq_base, 2.0f * inv_ndims * p);
294            // end of mrope
295
296            const float freq_factor = args.src2 ? ((device const float *) src2)[ic] : 1.0f;
297
298            rope_yarn(theta/freq_factor, args.freq_scale, corr_dims, i0, args.ext_factor, args.attn_factor, &cos_theta, &sin_theta);
299
300            device const T * const src = (device T *)(src0 + i3*args.nb03 + i2*args.nb02 + i1*args.nb01 + ic*args.nb00);
301            device       T * dst_data  = (device T *)( dst + i3*args.nb3  + i2*args.nb2  + i1*args.nb1  + ic*args.nb0);
302
303            const float x0 = src[0];
304            const float x1 = src[args.n_dims]; // different from kernel_rope_multi
305
306            dst_data[0]           = x0*cos_theta - x1*sin_theta;
307            dst_data[args.n_dims] = x0*sin_theta + x1*cos_theta; // different from kernel_rope_multi
308        } else {
309            device const T * const src = (device T *)(src0 + i3*args.nb03 + i2*args.nb02 + i1*args.nb01 + i0*args.nb00);
310            device       T * dst_data  = (device T *)( dst + i3*args.nb3  + i2*args.nb2  + i1*args.nb1  + i0*args.nb0);
311
312            dst_data[0] = src[0];
313            dst_data[1] = src[1];
314        }
315    }
316}
317
318typedef decltype(kernel_rope_norm<float>) kernel_rope_norm_t;
319typedef decltype(kernel_rope_neox<float>) kernel_rope_neox_t;
320typedef decltype(kernel_rope_multi<float>) kernel_rope_multi_t;
321typedef decltype(kernel_rope_vision<float>) kernel_rope_vision_t;
322
323template [[host_name("kernel_rope_norm_f32")]] kernel kernel_rope_norm_t kernel_rope_norm<float>;
324template [[host_name("kernel_rope_norm_f16")]] kernel kernel_rope_norm_t kernel_rope_norm<half>;
325
326template [[host_name("kernel_rope_neox_f32")]] kernel kernel_rope_neox_t kernel_rope_neox<float>;
327template [[host_name("kernel_rope_neox_f16")]] kernel kernel_rope_neox_t kernel_rope_neox<half>;
328
329template [[host_name("kernel_rope_multi_f32")]] kernel kernel_rope_multi_t kernel_rope_multi<float>;
330template [[host_name("kernel_rope_multi_f16")]] kernel kernel_rope_multi_t kernel_rope_multi<half>;
331
332template [[host_name("kernel_rope_vision_f32")]] kernel kernel_rope_vision_t kernel_rope_vision<float>;
333template [[host_name("kernel_rope_vision_f16")]] kernel kernel_rope_vision_t kernel_rope_vision<half>;