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
6.6 KiB262 linesraw
1#pragma once
2
3#include "common.h"
4
5void quantize_q1_0(device const float * src, device block_q1_0 & dst) {
6    float sum_abs = 0.0f;
7    for (int j = 0; j < QK1_0; j++) {
8        sum_abs += fabs(src[j]);
9    }
10    dst.d = sum_abs / QK1_0;
11
12    for (int j = 0; j < QK1_0 / 8; j++) {
13        dst.qs[j] = 0;
14    }
15    for (int j = 0; j < QK1_0; j++) {
16        if (src[j] >= 0.0f) {
17            dst.qs[j / 8] |= (1 << (j % 8));
18        }
19    }
20}
21
22void quantize_q2_0(device const float * src, device block_q2_0 & dst) {
23    float amax = 0.0f;
24    for (int j = 0; j < QK2_0; j++) {
25        float a = fabs(src[j]);
26        if (a > amax) amax = a;
27    }
28    const float d = amax;
29    dst.d = d;
30
31    const float id = d > 0.0f ? 1.0f / d : 0.0f;
32
33    for (int j = 0; j < QK2_0 / 4; j++) {
34        dst.qs[j] = 0;
35    }
36    for (int j = 0; j < QK2_0; j++) {
37        int q = (int)round(src[j] * id) + 1;
38        q = max(0, min(3, q));
39        dst.qs[j / 4] |= (q << (2 * (j % 4)));
40    }
41}
42
43void quantize_q4_0(device const float * src, device block_q4_0 & dst) {
44#pragma METAL fp math_mode(safe)
45    float amax = 0.0f; // absolute max
46    float max  = 0.0f;
47
48    for (int j = 0; j < QK4_0; j++) {
49        const float v = src[j];
50        if (amax < fabs(v)) {
51            amax = fabs(v);
52            max  = v;
53        }
54    }
55
56    const float d = max / -8;
57    const float id = d ? 1.0f/d : 0.0f;
58
59    dst.d = d;
60
61    for (int j = 0; j < QK4_0/2; ++j) {
62        const float x0 = src[0       + j]*id;
63        const float x1 = src[QK4_0/2 + j]*id;
64
65        const uint8_t xi0 = MIN(15, (int8_t)(x0 + 8.5f));
66        const uint8_t xi1 = MIN(15, (int8_t)(x1 + 8.5f));
67
68        dst.qs[j]  = xi0;
69        dst.qs[j] |= xi1 << 4;
70    }
71}
72
73void quantize_q4_1(device const float * src, device block_q4_1 & dst) {
74#pragma METAL fp math_mode(safe)
75    float min = FLT_MAX;
76    float max = -FLT_MAX;
77
78    for (int j = 0; j < QK4_1; j++) {
79        const float v = src[j];
80        if (min > v) min = v;
81        if (max < v) max = v;
82    }
83
84    const float d = (max - min) / ((1 << 4) - 1);
85    const float id = d ? 1.0f/d : 0.0f;
86
87    dst.d = d;
88    dst.m = min;
89
90    for (int j = 0; j < QK4_1/2; ++j) {
91        const float x0 = (src[0       + j] - min)*id;
92        const float x1 = (src[QK4_1/2 + j] - min)*id;
93
94        const uint8_t xi0 = MIN(15, (int8_t)(x0 + 0.5f));
95        const uint8_t xi1 = MIN(15, (int8_t)(x1 + 0.5f));
96
97        dst.qs[j]  = xi0;
98        dst.qs[j] |= xi1 << 4;
99    }
100}
101
102void quantize_q5_0(device const float * src, device block_q5_0 & dst) {
103#pragma METAL fp math_mode(safe)
104    float amax = 0.0f; // absolute max
105    float max  = 0.0f;
106
107    for (int j = 0; j < QK5_0; j++) {
108        const float v = src[j];
109        if (amax < fabs(v)) {
110            amax = fabs(v);
111            max  = v;
112        }
113    }
114
115    const float d = max / -16;
116    const float id = d ? 1.0f/d : 0.0f;
117
118    dst.d = d;
119
120    uint32_t qh = 0;
121    for (int j = 0; j < QK5_0/2; ++j) {
122        const float x0 = src[0       + j]*id;
123        const float x1 = src[QK5_0/2 + j]*id;
124
125        const uint8_t xi0 = MIN(31, (int8_t)(x0 + 16.5f));
126        const uint8_t xi1 = MIN(31, (int8_t)(x1 + 16.5f));
127
128        dst.qs[j] = (xi0 & 0xf) | ((xi1 & 0xf) << 4);
129        qh |= ((xi0 & 0x10u) >> 4) << (j + 0);
130        qh |= ((xi1 & 0x10u) >> 4) << (j + QK5_0/2);
131    }
132
133    thread const uint8_t * qh8 = (thread const uint8_t *)&qh;
134
135    for (int j = 0; j < 4; ++j) {
136        dst.qh[j] = qh8[j];
137    }
138}
139
140void quantize_q5_1(device const float * src, device block_q5_1 & dst) {
141#pragma METAL fp math_mode(safe)
142    float max = src[0];
143    float min = src[0];
144
145    for (int j = 1; j < QK5_1; j++) {
146        const float v = src[j];
147        min = v < min ? v : min;
148        max = v > max ? v : max;
149    }
150
151    const float d = (max - min) / 31;
152    const float id = d ? 1.0f/d : 0.0f;
153
154    dst.d = d;
155    dst.m = min;
156
157    uint32_t qh = 0;
158    for (int j = 0; j < QK5_1/2; ++j) {
159        const float x0 = (src[0       + j] - min)*id;
160        const float x1 = (src[QK5_1/2 + j] - min)*id;
161
162        const uint8_t xi0 = (uint8_t)(x0 + 0.5f);
163        const uint8_t xi1 = (uint8_t)(x1 + 0.5f);
164
165        dst.qs[j] = (xi0 & 0xf) | ((xi1 & 0xf) << 4);
166        qh |= ((xi0 & 0x10u) >> 4) << (j + 0);
167        qh |= ((xi1 & 0x10u) >> 4) << (j + QK5_1/2);
168    }
169
170    thread const uint8_t * qh8 = (thread const uint8_t *)&qh;
171
172    for (int j = 0; j < 4; ++j) {
173        dst.qh[j] = qh8[j];
174    }
175}
176
177void quantize_q8_0(device const float * src, device block_q8_0 & dst) {
178#pragma METAL fp math_mode(safe)
179    float amax = 0.0f; // absolute max
180
181    for (int j = 0; j < QK8_0; j++) {
182        const float v = src[j];
183        amax = MAX(amax, fabs(v));
184    }
185
186    const float d = amax / ((1 << 7) - 1);
187    const float id = d ? 1.0f/d : 0.0f;
188
189    dst.d = d;
190
191    for (int j = 0; j < QK8_0; ++j) {
192        const float x0 = src[j]*id;
193
194        dst.qs[j] = round(x0);
195    }
196}
197
198void quantize_iq4_nl(device const float * src, device block_iq4_nl & dst) {
199#pragma METAL fp math_mode(safe)
200    float amax = 0.0f; // absolute max
201    float max  = 0.0f;
202
203    for (int j = 0; j < QK4_NL; j++) {
204        const float v = src[j];
205        if (amax < fabs(v)) {
206            amax = fabs(v);
207            max  = v;
208        }
209    }
210
211    const float d = max / kvalues_iq4nl_f[0];
212    const float id = d ? 1.0f/d : 0.0f;
213
214    float sumqx = 0, sumq2 = 0;
215    for (int j = 0; j < QK4_NL/2; ++j) {
216        const float x0 = src[0        + j]*id;
217        const float x1 = src[QK4_NL/2 + j]*id;
218
219        const uint8_t xi0 = best_index_int8(16, kvalues_iq4nl_f, x0);
220        const uint8_t xi1 = best_index_int8(16, kvalues_iq4nl_f, x1);
221
222        dst.qs[j] = xi0 | (xi1 << 4);
223
224        const float v0 = kvalues_iq4nl_f[xi0];
225        const float v1 = kvalues_iq4nl_f[xi1];
226        const float w0 = src[0        + j]*src[0        + j];
227        const float w1 = src[QK4_NL/2 + j]*src[QK4_NL/2 + j];
228        sumqx += w0*v0*src[j] + w1*v1*src[QK4_NL/2 + j];
229        sumq2 += w0*v0*v0 + w1*v1*v1;
230
231    }
232
233    dst.d = sumq2 > 0 ? sumqx/sumq2 : d;
234}
235
236void quantize_tq2_0(device const float * src, device block_tq2_0 & dst) {
237#pragma METAL fp math_mode(safe)
238    float amax = 0.0f; // absolute max
239
240    for (int j = 0; j < QK_K; j++) {
241        const float v = src[j];
242        amax = MAX(amax, fabs(v));
243    }
244
245    const float d = amax;
246    const float id = d ? 1.0f/d : 0.0f;
247
248    dst.d = (half) d;
249
250    for (int j = 0; j < QK_K/4; j += 32) {
251        for (int m = 0; m < 32; ++m) {
252            uint8_t q = 0;
253            for (int n = 0; n < 4; ++n) {
254                // -1, 0, 1 -> 0, 1, 2
255                int xi = (int)round(src[m + n*32] * id) + 1;
256                q += (uint8_t)((xi & 3) << (2*n));
257            }
258            dst.qs[j + m] = q;
259        }
260        src += 4*32;
261    }
262}