char-fork/llama.cpp

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

Neo Zhangsycl : Support DSv4 OPs: LIGHTNING_INDEXER,DSV4_HC_COMB,DSV4_HC_POST,DSV4_HC_PRE (#26568)31558dbb7

char/aliceai-t5-moe
9.8 KiB280 linesraw
1#include "ggml-impl.h"
2#include "dsv4-hc.hpp"
3
4#include <cmath>
5
6static constexpr int DSV4_HC = 4;
7
8static void dsv4_hc_pre_f32_sycl(
9        const float * x, const float * weights, float * dst,
10        int64_t n_embd, int64_t hc, int64_t n_tokens,
11        int64_t sx0, int64_t sx1, int64_t sx2,
12        int64_t sw0, int64_t sw1,
13        int64_t sd0, int64_t sd1,
14        queue_ptr stream) {
15    const int64_t nr = n_embd * n_tokens;
16    const int64_t block_size = 256;
17    const int64_t num_blocks = (nr + block_size - 1) / block_size;
18
19    stream->parallel_for(
20        sycl::nd_range<1>(sycl::range<1>(num_blocks * block_size), sycl::range<1>(block_size)),
21        [=](sycl::nd_item<1> item) {
22            const int64_t ir = item.get_global_id(0);
23            if (ir >= nr) {
24                return;
25            }
26
27            const int64_t i0 = ir % n_embd;
28            const int64_t it = ir / n_embd;
29
30            float sum = x[i0*sx0 + it*sx2] * weights[it*sw1];
31            for (int64_t ih = 1; ih < hc; ++ih) {
32                const float xv = x[i0*sx0 + ih*sx1 + it*sx2];
33                const float wv = weights[ih*sw0 + it*sw1];
34                sum += xv * wv;
35            }
36
37            dst[i0*sd0 + it*sd1] = sum;
38        });
39}
40
41static void dsv4_hc_comb_norm_cols(float * comb, float eps) {
42    for (int idst = 0; idst < DSV4_HC; ++idst) {
43        float sum = eps;
44        for (int isrc = 0; isrc < DSV4_HC; ++isrc) {
45            sum += comb[idst + DSV4_HC*isrc];
46        }
47
48        const float inv_sum = 1.0f / sum;
49        for (int isrc = 0; isrc < DSV4_HC; ++isrc) {
50            comb[idst + DSV4_HC*isrc] *= inv_sum;
51        }
52    }
53}
54
55static void dsv4_hc_comb_norm_rows(float * comb, float eps) {
56    for (int isrc = 0; isrc < DSV4_HC; ++isrc) {
57        float sum = eps;
58        for (int idst = 0; idst < DSV4_HC; ++idst) {
59            sum += comb[idst + DSV4_HC*isrc];
60        }
61
62        const float inv_sum = 1.0f / sum;
63        for (int idst = 0; idst < DSV4_HC; ++idst) {
64            comb[idst + DSV4_HC*isrc] *= inv_sum;
65        }
66    }
67}
68
69static void dsv4_hc_comb_f32_sycl(
70        const float * mixes,
71        const float * scale,
72        const float * base,
73        float * dst,
74        int64_t n_tokens,
75        int64_t sm0,
76        int64_t sm1,
77        int64_t ss0,
78        int64_t sb0,
79        int64_t sd0,
80        int64_t sd1,
81        int64_t sd2,
82        float eps,
83        int32_t n_iter,
84        queue_ptr stream) {
85    constexpr int comb_offset = 2*DSV4_HC;
86
87    const int64_t block_size = 256;
88    const int64_t num_blocks = (n_tokens + block_size - 1) / block_size;
89
90    stream->parallel_for(
91        sycl::nd_range<1>(sycl::range<1>(num_blocks * block_size), sycl::range<1>(block_size)),
92        [=](sycl::nd_item<1> item_ct1) {
93            const int64_t it = item_ct1.get_global_id(0);
94
95            if (it >= n_tokens) {
96                return;
97            }
98
99            const float scale_comb = scale[2*ss0];
100            float comb[DSV4_HC*DSV4_HC];
101
102            for (int isrc = 0; isrc < DSV4_HC; ++isrc) {
103                float max = -INFINITY;
104                for (int idst = 0; idst < DSV4_HC; ++idst) {
105                    const int idx = idst + DSV4_HC*isrc;
106                    const float v = mixes[(comb_offset + idx)*sm0 + it*sm1] * scale_comb + base[(comb_offset + idx)*sb0];
107                    comb[idx] = v;
108                    max = fmaxf(max, v);
109                }
110
111                float sum = 0.0f;
112                for (int idst = 0; idst < DSV4_HC; ++idst) {
113                    const int idx = idst + DSV4_HC*isrc;
114                    const float v = expf(comb[idx] - max);
115                    comb[idx] = v;
116                    sum += v;
117                }
118
119                const float inv_sum = 1.0f / sum;
120                for (int idst = 0; idst < DSV4_HC; ++idst) {
121                    const int idx = idst + DSV4_HC*isrc;
122                    comb[idx] = comb[idx] * inv_sum + eps;
123                }
124            }
125
126            dsv4_hc_comb_norm_cols(comb, eps);
127            for (int32_t i = 1; i < n_iter; ++i) {
128                dsv4_hc_comb_norm_rows(comb, eps);
129                dsv4_hc_comb_norm_cols(comb, eps);
130            }
131
132            for (int isrc = 0; isrc < DSV4_HC; ++isrc) {
133                for (int idst = 0; idst < DSV4_HC; ++idst) {
134                    const int idx = idst + DSV4_HC*isrc;
135                    dst[idst*sd0 + isrc*sd1 + it*sd2] = comb[idx];
136                }
137            }
138        });
139}
140
141static void dsv4_hc_post_f32_sycl(
142        const float * x, const float * residual, const float * post, const float * comb, float * dst,
143        int64_t n_embd, int64_t hc, int64_t n_tokens,
144        int64_t sx0, int64_t sx1,
145        int64_t sr0, int64_t sr1, int64_t sr2,
146        int64_t sp0, int64_t sp1,
147        int64_t sc0, int64_t sc1, int64_t sc2,
148        int64_t sd0, int64_t sd1, int64_t sd2,
149        queue_ptr stream) {
150    const int64_t nr = n_embd * hc * n_tokens;
151    const int64_t block_size = 256;
152    const int64_t num_blocks = (nr + block_size - 1) / block_size;
153
154    stream->parallel_for(
155        sycl::nd_range<1>(sycl::range<1>(num_blocks * block_size), sycl::range<1>(block_size)),
156        [=](sycl::nd_item<1> item) {
157            const int64_t ir = item.get_global_id(0);
158            if (ir >= nr) {
159                return;
160            }
161
162            const int64_t i0   = ir % n_embd;
163            const int64_t idst = (ir / n_embd) % hc;
164            const int64_t it   = ir / (n_embd * hc);
165
166            float sum = x[i0*sx0 + it*sx1] * post[idst*sp0 + it*sp1];
167            for (int64_t isrc = 0; isrc < hc; ++isrc) {
168                sum += residual[i0*sr0 + isrc*sr1 + it*sr2] * comb[idst*sc0 + isrc*sc1 + it*sc2];
169            }
170
171            dst[i0*sd0 + idst*sd1 + it*sd2] = sum;
172        });
173}
174
175void ggml_sycl_op_dsv4_hc_pre(ggml_backend_sycl_context & ctx, ggml_tensor * dst) {
176    scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/2);
177    const ggml_tensor * x       = dst->src[0];
178    const ggml_tensor * weights = dst->src[1];
179
180    GGML_ASSERT(x->type == GGML_TYPE_F32);
181    GGML_ASSERT(weights->type == GGML_TYPE_F32);
182    GGML_ASSERT(dst->type == GGML_TYPE_F32);
183
184    GGML_TENSOR_LOCALS(size_t, nbx, x,       nb);
185    GGML_TENSOR_LOCALS(size_t, nbw, weights, nb);
186    GGML_TENSOR_LOCALS(size_t, nbd, dst,     nb);
187
188    const int64_t n_embd   = x->ne[0];
189    const int64_t hc       = x->ne[1];
190    const int64_t n_tokens = x->ne[2];
191
192    queue_ptr stream = ctx.stream();
193
194    dsv4_hc_pre_f32_sycl(
195            (const float *) x->data, (const float *) weights->data, (float *) dst->data,
196            n_embd, hc, n_tokens,
197            nbx0 / sizeof(float), nbx1 / sizeof(float), nbx2 / sizeof(float),
198            nbw0 / sizeof(float), nbw1 / sizeof(float),
199            nbd0 / sizeof(float), nbd1 / sizeof(float),
200            stream);
201}
202
203void ggml_sycl_op_dsv4_hc_comb(ggml_backend_sycl_context & ctx, ggml_tensor * dst) {
204    scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/3);
205
206    const ggml_tensor * mixes = dst->src[0];
207    const ggml_tensor * scale = dst->src[1];
208    const ggml_tensor * base  = dst->src[2];
209
210    GGML_ASSERT(mixes->type == GGML_TYPE_F32);
211    GGML_ASSERT(scale->type == GGML_TYPE_F32);
212    GGML_ASSERT(base->type == GGML_TYPE_F32);
213    GGML_ASSERT(dst->type == GGML_TYPE_F32);
214
215    constexpr int64_t hc_mix_dim = (2 + DSV4_HC)*DSV4_HC;
216
217    GGML_ASSERT(mixes->ne[0] == hc_mix_dim);
218    GGML_ASSERT(dst->ne[0] == DSV4_HC);
219    GGML_ASSERT(dst->ne[1] == DSV4_HC);
220    GGML_ASSERT(dst->ne[2] == mixes->ne[1]);
221    GGML_ASSERT(scale->ne[0] >= 3);
222    GGML_ASSERT(base->ne[0] == hc_mix_dim);
223
224    GGML_TENSOR_LOCALS(size_t, nbm, mixes, nb);
225    GGML_TENSOR_LOCALS(size_t, nbs, scale, nb);
226    GGML_TENSOR_LOCALS(size_t, nbb, base,  nb);
227    GGML_TENSOR_LOCALS(size_t, nbd, dst,   nb);
228
229    const int64_t n_tokens = mixes->ne[1];
230    const float eps = ggml_get_op_params_f32(dst, 0);
231    const int32_t n_iter = ggml_get_op_params_i32(dst, 1);
232
233    queue_ptr stream = ctx.stream();
234
235    dsv4_hc_comb_f32_sycl(
236            (const float *) mixes->data, (const float *) scale->data, (const float *) base->data, (float *) dst->data,
237            n_tokens,
238            nbm0 / sizeof(float), nbm1 / sizeof(float),
239            nbs0 / sizeof(float),
240            nbb0 / sizeof(float),
241            nbd0 / sizeof(float), nbd1 / sizeof(float), nbd2 / sizeof(float),
242            eps, n_iter, stream);
243}
244
245void ggml_sycl_op_dsv4_hc_post(ggml_backend_sycl_context & ctx, ggml_tensor * dst) {
246    scope_op_debug_print scope_dbg_print(__func__, dst, /*num_src=*/4);
247    const ggml_tensor * x        = dst->src[0];
248    const ggml_tensor * residual = dst->src[1];
249    const ggml_tensor * post     = dst->src[2];
250    const ggml_tensor * comb     = dst->src[3];
251
252    GGML_ASSERT(x->type == GGML_TYPE_F32);
253    GGML_ASSERT(residual->type == GGML_TYPE_F32);
254    GGML_ASSERT(post->type == GGML_TYPE_F32);
255    GGML_ASSERT(comb->type == GGML_TYPE_F32);
256    GGML_ASSERT(dst->type == GGML_TYPE_F32);
257
258    GGML_TENSOR_LOCALS(size_t, nbx, x,        nb);
259    GGML_TENSOR_LOCALS(size_t, nbr, residual, nb);
260    GGML_TENSOR_LOCALS(size_t, nbp, post,     nb);
261    GGML_TENSOR_LOCALS(size_t, nbc, comb,     nb);
262    GGML_TENSOR_LOCALS(size_t, nbd, dst,      nb);
263
264    const int64_t n_embd   = x->ne[0];
265    const int64_t n_tokens = x->ne[1];
266    const int64_t hc       = residual->ne[1];
267
268    queue_ptr stream = ctx.stream();
269
270    dsv4_hc_post_f32_sycl(
271            (const float *) x->data, (const float *) residual->data,
272            (const float *) post->data, (const float *) comb->data, (float *) dst->data,
273            n_embd, hc, n_tokens,
274            nbx0 / sizeof(float), nbx1 / sizeof(float),
275            nbr0 / sizeof(float), nbr1 / sizeof(float), nbr2 / sizeof(float),
276            nbp0 / sizeof(float), nbp1 / sizeof(float),
277            nbc0 / sizeof(float), nbc1 / sizeof(float), nbc2 / sizeof(float),
278            nbd0 / sizeof(float), nbd1 / sizeof(float), nbd2 / sizeof(float),
279            stream);
280}