char-fork/llama.cpp

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

Jeff Bolzvulkan: Support Q2_0 (#25430)788e07dc9

char/aliceai-t5-moe
9.5 KiB350 linesraw
1#version 450
2
3#include "types.glsl"
4
5#if defined(SET_ROWS) && QUANT_K == 1
6layout(local_size_x = 512, local_size_y = 1, local_size_z = 1) in;
7const uint BLOCK_SIZE = 512;
8#else
9layout(local_size_x = 32, local_size_y = 1, local_size_z = 1) in;
10const uint BLOCK_SIZE = 32;
11#endif
12
13layout (binding = 0) readonly buffer S {S_TYPE data_s[];};
14
15#if defined(SET_ROWS)
16#include "generic_binary_head.glsl"
17layout (binding = 1) readonly buffer C {B_TYPE data_i[];};
18layout (binding = 2) writeonly buffer Q {A_TYPE data_q[];};
19
20#if B_SIZE == 64
21#define DATA_I_SWIZZLE .x
22#else
23#define DATA_I_SWIZZLE
24#endif
25
26#else
27#include "generic_unary_head.glsl"
28layout (binding = 1) writeonly buffer Q {A_TYPE data_q[];};
29#endif
30
31#if defined(DATA_A_Q4_0)
32void quantize(uint dst_idx, uint src_idx)
33{
34    float amax = 0.0;
35    float vmax = 0.0;
36
37    [[unroll]] for (int j = 0; j < QUANT_K_Q4_0; ++j) {
38        const float v = float(data_s[src_idx + j]);
39        if (amax < abs(v)) {
40            amax = abs(v);
41            vmax = v;
42        }
43    }
44
45    const float d  = vmax / -8;
46    const float id = (d != 0.0) ? 1.0/d : 0.0;
47
48    data_q[dst_idx].d = float16_t(d);
49
50    [[unroll]] for (int j = 0; j < QUANT_K_Q4_0/2; ++j) {
51        const float x0 = float(data_s[src_idx + 0              + j])*id;
52        const float x1 = float(data_s[src_idx + QUANT_K_Q4_0/2 + j])*id;
53
54        const uint xi0 = min(15, int(x0 + 8.5));
55        const uint xi1 = min(15, int(x1 + 8.5));
56
57        data_q[dst_idx].qs[j]  = uint8_t(xi0 | (xi1 << 4));
58    }
59}
60#endif
61
62#if defined(DATA_A_Q4_1)
63void quantize(uint dst_idx, uint src_idx)
64{
65    float vmin = 1.0/0.0;
66    float vmax = -vmin;
67
68    [[unroll]] for (int j = 0; j < QUANT_K_Q4_1; ++j) {
69        const float v = float(data_s[src_idx + j]);
70
71        if (v < vmin) vmin = v;
72        if (v > vmax) vmax = v;
73    }
74
75    const float d  = (vmax - vmin) / ((1 << 4) - 1);
76    const float id = (d != 0.0) ? 1.0/d : 0.0;
77
78    data_q[dst_idx].d = float16_t(d);
79    data_q[dst_idx].m = float16_t(vmin);
80
81    [[unroll]] for (int j = 0; j < QUANT_K_Q4_1/2; ++j) {
82        const float x0 = (float(data_s[src_idx + 0              + j]) - vmin)*id;
83        const float x1 = (float(data_s[src_idx + QUANT_K_Q4_1/2 + j]) - vmin)*id;
84
85        const uint xi0 = min(15, int(x0 + 0.5));
86        const uint xi1 = min(15, int(x1 + 0.5));
87
88        data_q[dst_idx].qs[j]  = uint8_t(xi0 | (xi1 << 4));
89    }
90}
91#endif
92
93#if defined(DATA_A_Q5_0)
94void quantize(uint dst_idx, uint src_idx)
95{
96    float amax = 0.0;
97    float vmax = 0.0;
98
99    [[unroll]] for (int j = 0; j < QUANT_K_Q5_0; ++j) {
100        const float v = float(data_s[src_idx + j]);
101        if (amax < abs(v)) {
102            amax = abs(v);
103            vmax = v;
104        }
105    }
106
107    const float d  = vmax / -16;
108    const float id = (d != 0.0) ? 1.0/d : 0.0;
109
110    data_q[dst_idx].d = float16_t(d);
111
112    uint32_t qh = 0;
113    [[unroll]] for (int j = 0; j < QUANT_K_Q5_0/2; ++j) {
114        const float x0 = float(data_s[src_idx + 0              + j])*id;
115        const float x1 = float(data_s[src_idx + QUANT_K_Q5_0/2 + j])*id;
116
117        const uint xi0 = min(31, int(x0 + 16.5));
118        const uint xi1 = min(31, int(x1 + 16.5));
119
120        data_q[dst_idx].qs[j]  = uint8_t((xi0 & 0xf) | ((xi1 & 0xf) << 4));
121        qh |= ((xi0 & 0x10u) >> 4) << (j + 0);
122        qh |= ((xi1 & 0x10u) >> 4) << (j + QUANT_K_Q5_0/2);
123    }
124    data_q[dst_idx].qh[0] = uint16_t(qh & 0xFFFF);
125    data_q[dst_idx].qh[1] = uint16_t(qh >> 16);
126}
127#endif
128
129#if defined(DATA_A_Q5_1)
130void quantize(uint dst_idx, uint src_idx)
131{
132    float min = float(data_s[src_idx + 0]);
133    float max = min;
134
135    [[unroll]] for (int j = 1; j < QUANT_K_Q5_1; ++j) {
136        const float v = float(data_s[src_idx + j]);
137        min = v < min ? v : min;
138        max = v > max ? v : max;
139    }
140
141    const float d  = (max - min) / 31;
142    const float id = (d != 0) ? 1.0/d : 0.0;
143
144    data_q[dst_idx].d = float16_t(d);
145    data_q[dst_idx].m = float16_t(min);
146
147    uint32_t qh = 0;
148    [[unroll]] for (int j = 0; j < QUANT_K_Q5_1/2; ++j) {
149        const float x0 = (float(data_s[src_idx + 0              + j]) - min)*id;
150        const float x1 = (float(data_s[src_idx + QUANT_K_Q5_1/2 + j]) - min)*id;
151
152        const uint xi0 = uint(x0 + 0.5);
153        const uint xi1 = uint(x1 + 0.5);
154
155        data_q[dst_idx].qs[j]  = uint8_t((xi0 & 0xf) | ((xi1 & 0xf) << 4));
156        qh |= ((xi0 & 0x10u) >> 4) << (j + 0);
157        qh |= ((xi1 & 0x10u) >> 4) << (j + QUANT_K_Q5_1/2);
158    }
159    data_q[dst_idx].qh = qh;
160}
161#endif
162
163#if defined(DATA_A_Q8_0)
164void quantize(uint dst_idx, uint src_idx)
165{
166    float amax = 0.0; // absolute max
167
168    [[unroll]] for (int j = 0; j < QUANT_K_Q8_0; j++) {
169        const float v = float(data_s[src_idx + j]);
170        amax = max(amax, abs(v));
171    }
172
173    const float d = amax / ((1 << 7) - 1);
174    const float id = (d != 0.0) ? 1.0/d : 0.0;
175
176    data_q[dst_idx].d = float16_t(d);
177
178    [[unroll]] for (int j = 0; j < QUANT_K_Q8_0; ++j) {
179        const float x0 = float(data_s[src_idx + j])*id;
180
181        data_q[dst_idx].qs[j] = int8_t(round(x0));
182    }
183}
184#endif
185
186#if defined(DATA_A_Q1_0)
187void quantize(uint dst_idx, uint src_idx)
188{
189    float sum_abs = 0.0;
190
191    [[unroll]] for (int j = 0; j < QUANT_K_Q1_0; j++) {
192        sum_abs += abs(float(data_s[src_idx + j]));
193    }
194
195    const float d = sum_abs / QUANT_K_Q1_0;
196
197    data_q[dst_idx].d = float16_t(d);
198
199    [[unroll]] for (int j = 0; j < QUANT_K_Q1_0 / 8; ++j) {
200        data_q[dst_idx].qs[j] = uint8_t(0);
201    }
202
203    [[unroll]] for (int j = 0; j < QUANT_K_Q1_0; ++j) {
204        if (float(data_s[src_idx + j]) >= 0.0) {
205            data_q[dst_idx].qs[j / 8] |= uint8_t(1 << (j % 8));
206        }
207    }
208}
209#endif
210
211#if defined(DATA_A_Q2_0)
212uint quantize_q2_0(float x)
213{
214    const int q = int(x >= 0.0f ? floor(x + 0.5f) : ceil(x - 0.5f)) + 1;
215    return uint(clamp(q, 0, 3));
216}
217
218void quantize(uint dst_idx, uint src_idx)
219{
220    float amax = 0.0f;
221
222    [[unroll]] for (int j = 0; j < QUANT_K_Q2_0; ++j) {
223        amax = max(amax, abs(float(data_s[src_idx + j])));
224    }
225
226    const float d = amax;
227    const float id = d != 0.0f ? 1.0f / d : 0.0f;
228
229    data_q[dst_idx].d = float16_t(d);
230
231    [[unroll]] for (int j = 0; j < QUANT_K_Q2_0 / 4; ++j) {
232        const uint q0 = quantize_q2_0(float(data_s[src_idx + 4*j    ]) * id);
233        const uint q1 = quantize_q2_0(float(data_s[src_idx + 4*j + 1]) * id);
234        const uint q2 = quantize_q2_0(float(data_s[src_idx + 4*j + 2]) * id);
235        const uint q3 = quantize_q2_0(float(data_s[src_idx + 4*j + 3]) * id);
236        data_q[dst_idx].qs[j] = uint8_t(q0 | (q1 << 2u) | (q2 << 4u) | (q3 << 6u));
237    }
238}
239#endif
240
241#if defined(DATA_A_IQ4_NL)
242uint best_index(float x) {
243    if (x <= kvalues_iq4nl[0]) return 0;
244    if (x >= kvalues_iq4nl[15]) return 15;
245    int ml = 0, mu = 15;
246    while (mu-ml > 1) {
247        int mav = (ml+mu)/2;
248        if (x < kvalues_iq4nl[mav]) mu = mav; else ml = mav;
249    }
250    return x - kvalues_iq4nl[mu-1] < kvalues_iq4nl[mu] - x ? mu-1 : mu;
251}
252
253void quantize(uint dst_idx, uint src_idx)
254{
255    float amax = 0.0;
256    float vmax = 0.0;
257
258    [[unroll]] for (int j = 0; j < QUANT_K_IQ4_NL; ++j) {
259        const float v = float(data_s[src_idx + j]);
260        if (amax < abs(v)) {
261            amax = abs(v);
262            vmax = v;
263        }
264    }
265
266    float d = vmax / kvalues_iq4nl[0];
267    const float id = (d != 0.0) ? 1.0/d : 0.0;
268
269    float sumqx = 0, sumq2 = 0;
270    [[unroll]] for (int j = 0; j < QUANT_K_IQ4_NL/2; ++j) {
271        const float x0 = float(data_s[src_idx + 0                + j])*id;
272        const float x1 = float(data_s[src_idx + QUANT_K_IQ4_NL/2 + j])*id;
273        const uint xi0 = best_index(x0);
274        const uint xi1 = best_index(x1);
275        data_q[dst_idx].qs[j] = uint8_t(xi0 | (xi1 << 4));
276        const float v0 = kvalues_iq4nl[xi0];
277        const float v1 = kvalues_iq4nl[xi1];
278        const float w0 = float(data_s[src_idx + 0                + j])*float(data_s[src_idx + 0                + j]);
279        const float w1 = float(data_s[src_idx + QUANT_K_IQ4_NL/2 + j])*float(data_s[src_idx + QUANT_K_IQ4_NL/2 + j]);
280        sumqx += w0*v0*float(data_s[src_idx + j]) + w1*v1*float(data_s[src_idx + QUANT_K_IQ4_NL/2 + j]);
281        sumq2 += w0*v0*v0 + w1*v1*v1;
282    }
283
284    data_q[dst_idx].d = float16_t(sumq2 > 0 ? sumqx/sumq2 : d);
285
286}
287#endif
288
289#if defined(DATA_A_F32) || defined(DATA_A_F16)
290void quantize(uint dst_idx, uint src_idx)
291{
292    data_q[dst_idx] = A_TYPE(float(data_s[src_idx]));
293}
294#endif
295
296#if defined(DATA_A_BF16)
297void quantize(uint dst_idx, uint src_idx)
298{
299    data_q[dst_idx] = A_TYPE(fp32_to_bf16(float(data_s[src_idx])));
300}
301#endif
302
303#if defined(SET_ROWS)
304
305void main() {
306#ifdef NEEDS_INIT_IQ_SHMEM
307    init_iq_shmem(gl_WorkGroupSize);
308#endif
309
310    const uint idx = ((gl_WorkGroupID.z * 262144 + gl_WorkGroupID.y * 512 + gl_WorkGroupID.x) * BLOCK_SIZE + gl_LocalInvocationID.x) * QUANT_K;
311
312    if (idx >= p.ne) {
313        return;
314    }
315
316    uint i00, i01, i02, i03;
317    get_indices(idx, i00, i01, i02, i03);
318
319    uint i12 = fastmod(i03, p.ne12);
320    uint i11 = fastmod(i02, p.ne11);
321    uint i10 = i01;
322
323    uint i1 = data_i[src1_idx(i10, i11, i12, 0) + get_boffset()] DATA_I_SWIZZLE;
324
325    uint src0_idx = src0_idx(i00, i01, i02, i03) + get_aoffset();
326    uint dst_idx = dst_idx(i00 / QUANT_K, i1, i02, i03) + get_doffset();
327
328    quantize(dst_idx, src0_idx);
329}
330
331#else
332
333void main() {
334#ifdef NEEDS_INIT_IQ_SHMEM
335    init_iq_shmem(gl_WorkGroupSize);
336#endif
337
338    const uint idx = (gl_WorkGroupID.z * 262144 + gl_WorkGroupID.y * 512 + gl_WorkGroupID.x * 32 + gl_LocalInvocationID.x) * QUANT_K;
339
340    if (idx >= p.ne) {
341        return;
342    }
343
344    uint dst_idx = dst_idx_quant(idx, QUANT_K);
345    uint src_idx = get_aoffset() + src0_idx(idx);
346
347    quantize(dst_idx, src_idx);
348}
349
350#endif