1#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
10pub enum GgmlType {
11 F32,
12 F16,
13 Bf16,
14 Q4_0,
15 Q4_1,
16 Q5_0,
17 Q5_1,
18 Q8_0,
19 Q2K,
20 Q3K,
21 Q4K,
22 Q5K,
23 Q6K,
24 Iq4Nl,
25 Iq4Xs,
26 Mxfp4,
27}
28
29const QK_K: usize = 256;
31
32impl GgmlType {
33 pub fn from_id(id: u32) -> Result<GgmlType, u32> {
35 Ok(match id {
36 0 => GgmlType::F32,
37 1 => GgmlType::F16,
38 2 => GgmlType::Q4_0,
39 3 => GgmlType::Q4_1,
40 6 => GgmlType::Q5_0,
41 7 => GgmlType::Q5_1,
42 8 => GgmlType::Q8_0,
43 10 => GgmlType::Q2K,
44 11 => GgmlType::Q3K,
45 12 => GgmlType::Q4K,
46 13 => GgmlType::Q5K,
47 14 => GgmlType::Q6K,
48 20 => GgmlType::Iq4Nl,
49 23 => GgmlType::Iq4Xs,
50 30 => GgmlType::Bf16,
51 39 => GgmlType::Mxfp4,
52 other => return Err(other),
53 })
54 }
55
56 pub fn id(self) -> u32 {
58 match self {
59 GgmlType::F32 => 0,
60 GgmlType::F16 => 1,
61 GgmlType::Q4_0 => 2,
62 GgmlType::Q4_1 => 3,
63 GgmlType::Q5_0 => 6,
64 GgmlType::Q5_1 => 7,
65 GgmlType::Q8_0 => 8,
66 GgmlType::Q2K => 10,
67 GgmlType::Q3K => 11,
68 GgmlType::Q4K => 12,
69 GgmlType::Q5K => 13,
70 GgmlType::Q6K => 14,
71 GgmlType::Iq4Nl => 20,
72 GgmlType::Iq4Xs => 23,
73 GgmlType::Bf16 => 30,
74 GgmlType::Mxfp4 => 39,
75 }
76 }
77
78 pub fn name(self) -> &'static str {
80 match self {
81 GgmlType::F32 => "f32",
82 GgmlType::F16 => "f16",
83 GgmlType::Bf16 => "bf16",
84 GgmlType::Q4_0 => "q4_0",
85 GgmlType::Q4_1 => "q4_1",
86 GgmlType::Q5_0 => "q5_0",
87 GgmlType::Q5_1 => "q5_1",
88 GgmlType::Q8_0 => "q8_0",
89 GgmlType::Q2K => "q2_K",
90 GgmlType::Q3K => "q3_K",
91 GgmlType::Q4K => "q4_K",
92 GgmlType::Q5K => "q5_K",
93 GgmlType::Q6K => "q6_K",
94 GgmlType::Iq4Nl => "iq4_nl",
95 GgmlType::Iq4Xs => "iq4_xs",
96 GgmlType::Mxfp4 => "mxfp4",
97 }
98 }
99
100 pub fn block_len(self) -> usize {
102 match self {
103 GgmlType::F32 | GgmlType::F16 | GgmlType::Bf16 => 1,
104 GgmlType::Q4_0
105 | GgmlType::Q4_1
106 | GgmlType::Q5_0
107 | GgmlType::Q5_1
108 | GgmlType::Q8_0
109 | GgmlType::Iq4Nl
110 | GgmlType::Mxfp4 => 32,
111 GgmlType::Q2K | GgmlType::Q3K | GgmlType::Q4K | GgmlType::Q5K | GgmlType::Q6K | GgmlType::Iq4Xs => QK_K,
112 }
113 }
114
115 pub fn block_bytes(self) -> usize {
117 match self {
118 GgmlType::F32 => 4,
119 GgmlType::F16 | GgmlType::Bf16 => 2,
120 GgmlType::Q4_0 => 2 + 16,
121 GgmlType::Q4_1 => 2 + 2 + 16,
122 GgmlType::Q5_0 => 2 + 4 + 16,
123 GgmlType::Q5_1 => 2 + 2 + 4 + 16,
124 GgmlType::Q8_0 => 2 + 32,
125 GgmlType::Mxfp4 => 1 + 16,
126 GgmlType::Q2K => QK_K / 16 + QK_K / 4 + 2 + 2,
127 GgmlType::Q3K => QK_K / 8 + QK_K / 4 + 12 + 2,
128 GgmlType::Q4K => 2 + 2 + 12 + QK_K / 2,
129 GgmlType::Q5K => 2 + 2 + 12 + QK_K / 8 + QK_K / 2,
130 GgmlType::Q6K => QK_K / 2 + QK_K / 4 + QK_K / 16 + 2,
131 GgmlType::Iq4Nl => 2 + 16,
132 GgmlType::Iq4Xs => 2 + 2 + QK_K / 64 + QK_K / 2,
133 }
134 }
135
136 pub fn bytes_for(self, n: usize) -> usize {
138 assert!(
139 n % self.block_len() == 0,
140 "{n} weights are not a whole number of {} blocks of {}",
141 self.name(),
142 self.block_len()
143 );
144 n / self.block_len() * self.block_bytes()
145 }
146
147 pub fn dequantize(self, bytes: &[u8], out: &mut Vec<f32>) {
149 let bb = self.block_bytes();
150 assert!(
151 bytes.len() % bb == 0,
152 "{} bytes are not a whole number of {} blocks",
153 bytes.len(),
154 self.name()
155 );
156 out.reserve(bytes.len() / bb * self.block_len());
157 for b in bytes.chunks_exact(bb) {
158 match self {
159 GgmlType::F32 => out.push(f32::from_le_bytes([b[0], b[1], b[2], b[3]])),
160 GgmlType::F16 => out.push(f16_to_f32(u16::from_le_bytes([b[0], b[1]]))),
161 GgmlType::Bf16 => out.push(bf16_to_f32(u16::from_le_bytes([b[0], b[1]]))),
162 GgmlType::Q4_0 => q4_0(b, out),
163 GgmlType::Q4_1 => q4_1(b, out),
164 GgmlType::Q5_0 => q5_0(b, out),
165 GgmlType::Q5_1 => q5_1(b, out),
166 GgmlType::Q8_0 => q8_0(b, out),
167 GgmlType::Mxfp4 => mxfp4(b, out),
168 GgmlType::Q2K => q2_k(b, out),
169 GgmlType::Q3K => q3_k(b, out),
170 GgmlType::Q4K => q4_k(b, out),
171 GgmlType::Q5K => q5_k(b, out),
172 GgmlType::Q6K => q6_k(b, out),
173 GgmlType::Iq4Nl => iq4_nl(b, out),
174 GgmlType::Iq4Xs => iq4_xs(b, out),
175 }
176 }
177 }
178}
179
180pub fn f32_to_f16(x: f32) -> u16 {
183 let b = x.to_bits();
184 let sign = ((b >> 16) & 0x8000) as u16;
185 let exp = ((b >> 23) & 0xff) as i32;
186 let mant = b & 0x7f_ffff;
187 if exp == 0xff {
188 return sign | 0x7c00 | if mant != 0 { 0x0200 } else { 0 };
189 }
190 if exp == 0 {
191 return sign;
192 }
193 let e = exp - 127;
194 if e > 15 {
195 return sign | 0x7c00;
196 }
197 if e >= -14 {
198 let (m, rem) = (mant >> 13, mant & 0x1fff);
199 let h = (((e + 15) as u32) << 10) | m;
200 let up = rem > 0x1000 || (rem == 0x1000 && m & 1 == 1);
201 return sign | (h + u32::from(up)) as u16;
202 }
203 let s = (-(e + 1)) as u32;
205 if s > 24 {
206 return sign;
207 }
208 let sig = 0x80_0000 | mant;
209 let (n, rem, half) = (sig >> s, sig & ((1u32 << s) - 1), 1u32 << (s - 1));
210 let up = rem > half || (rem == half && n & 1 == 1);
211 sign | (n + u32::from(up)) as u16
212}
213
214pub fn f16_to_f32(h: u16) -> f32 {
216 let sign = ((h >> 15) & 1) as u32;
217 let exp = ((h >> 10) & 0x1f) as u32;
218 let mant = (h & 0x3ff) as u32;
219 let bits = match (exp, mant) {
220 (0, 0) => sign << 31,
221 (0, _) => {
222 let mut e: i32 = -1;
223 let mut m = mant;
224 while m & 0x400 == 0 {
225 m <<= 1;
226 e -= 1;
227 }
228 (sign << 31) | (((e + 1 + 127 - 14) as u32) << 23) | ((m & 0x3ff) << 13)
229 }
230 (0x1f, 0) => (sign << 31) | 0x7f80_0000,
231 (0x1f, _) => (sign << 31) | 0x7fc0_0000 | (mant << 13),
232 _ => (sign << 31) | ((exp + 127 - 15) << 23) | (mant << 13),
233 };
234 f32::from_bits(bits)
235}
236
237pub fn bf16_to_f32(h: u16) -> f32 {
239 f32::from_bits((h as u32) << 16)
240}
241
242pub fn f32_to_bf16(x: f32) -> u16 {
244 let b = x.to_bits();
245 if x.is_nan() {
246 return ((b >> 16) | 0x0040) as u16;
247 }
248 ((b + 0x7fff + ((b >> 16) & 1)) >> 16) as u16
249}
250
251pub fn e4m3fn_to_f32(b: u8) -> f32 {
254 let sign = u32::from(b >> 7) << 31;
255 let (e, m) = (u32::from((b >> 3) & 0xf), u32::from(b & 7));
256 if e == 0xf && m == 7 {
257 return f32::from_bits(sign | 0x7f80_0000 | m << 20);
258 }
259 let magnitude = if e == 0 { m as f32 / 8.0 * 2f32.powi(-6) } else { (1.0 + m as f32 / 8.0) * 2f32.powi(e as i32 - 7) };
260 f32::from_bits(sign | magnitude.to_bits())
261}
262
263pub fn e5m2_to_f32(b: u8) -> f32 {
265 f16_to_f32(u16::from(b) << 8)
266}
267
268#[derive(Clone, Debug)]
273pub struct ScaleGrid {
274 weight: Vec<usize>,
275 values: Vec<f32>,
276 axes: Vec<Option<(usize, usize)>>,
278}
279
280impl ScaleGrid {
281 pub fn new(weight: &[usize], dims: &[usize], values: Vec<f32>, block: Option<&[usize]>) -> Result<ScaleGrid, String> {
284 let count: usize = dims.iter().product();
285 if values.len() != count {
286 return Err(format!("a scale of axes {dims:?} holds {count} values, not {}", values.len()));
287 }
288 if dims.len() > weight.len() {
289 return Err(format!("a scale of axes {dims:?} has more axes than its weight's {weight:?}"));
290 }
291 let repeat: Vec<usize> = match block {
292 None => vec![1; dims.len()],
293 Some(b) if b.len() <= dims.len() && b.iter().all(|&x| x > 0) => {
294 let offset = dims.len() - b.len();
295 (0..dims.len()).map(|d| if d < offset { 1 } else { b[d - offset] }).collect()
296 }
297 Some(b) => return Err(format!("a block of {b:?} over a scale of axes {dims:?}")),
298 };
299 let mut stride = vec![1usize; dims.len()];
300 for d in (0..dims.len().saturating_sub(1)).rev() {
301 stride[d] = stride[d + 1] * dims[d + 1];
302 }
303 let mut axes = Vec::with_capacity(weight.len());
304 for (d, &w) in weight.iter().enumerate() {
305 let expanded = if d < dims.len() { (dims[d] * repeat[d]).min(w) } else { 1 };
306 axes.push(if expanded == w && w != 1 {
307 Some((repeat[d], stride[d]))
308 } else if expanded == 1 {
309 None
310 } else {
311 return Err(format!(
312 "a scale of axes {dims:?} in blocks of {block:?} spans {expanded} on axis {d} of a weight of {weight:?}"
313 ));
314 });
315 }
316 Ok(ScaleGrid { weight: weight.to_vec(), values, axes })
317 }
318
319 pub fn apply(&self, first: usize, values: &mut [f32]) {
321 let mut index = vec![0usize; self.weight.len()];
322 let mut rest = first;
323 for d in (0..self.weight.len()).rev() {
324 index[d] = rest % self.weight[d].max(1);
325 rest /= self.weight[d].max(1);
326 }
327 for v in values.iter_mut() {
328 let at: usize = self.axes.iter().zip(&index).map(|(a, &i)| a.map_or(0, |(div, stride)| i / div * stride)).sum();
329 *v *= self.values[at];
330 for d in (0..index.len()).rev() {
331 index[d] += 1;
332 if index[d] < self.weight[d] {
333 break;
334 }
335 index[d] = 0;
336 }
337 }
338 }
339}
340
341fn half(b: &[u8], at: usize) -> f32 {
342 f16_to_f32(u16::from_le_bytes([b[at], b[at + 1]]))
343}
344
345fn q4_0(b: &[u8], y: &mut Vec<f32>) {
346 let d = half(b, 0);
347 let qs = &b[2..18];
348 let (lo, hi): (Vec<f32>, Vec<f32>) = qs
349 .iter()
350 .map(|&q| (((q & 0x0f) as i32 - 8) as f32 * d, ((q >> 4) as i32 - 8) as f32 * d))
351 .unzip();
352 y.extend(lo);
353 y.extend(hi);
354}
355
356fn q4_1(b: &[u8], y: &mut Vec<f32>) {
357 let (d, m) = (half(b, 0), half(b, 2));
358 let qs = &b[4..20];
359 y.extend(qs.iter().map(|&q| (q & 0x0f) as f32 * d + m));
360 y.extend(qs.iter().map(|&q| (q >> 4) as f32 * d + m));
361}
362
363fn q5_0(b: &[u8], y: &mut Vec<f32>) {
364 let d = half(b, 0);
365 let qh = u32::from_le_bytes([b[2], b[3], b[4], b[5]]);
366 let qs = &b[6..22];
367 let x = |j: usize, q: u8| -> (f32, f32) {
368 let xh0 = (((qh >> j) << 4) & 0x10) as u8;
369 let xh1 = ((qh >> (j + 12)) & 0x10) as u8;
370 (
371 (((q & 0x0f) | xh0) as i32 - 16) as f32 * d,
372 (((q >> 4) | xh1) as i32 - 16) as f32 * d,
373 )
374 };
375 let (lo, hi): (Vec<f32>, Vec<f32>) = qs.iter().enumerate().map(|(j, &q)| x(j, q)).unzip();
376 y.extend(lo);
377 y.extend(hi);
378}
379
380fn q5_1(b: &[u8], y: &mut Vec<f32>) {
381 let (d, m) = (half(b, 0), half(b, 2));
382 let qh = u32::from_le_bytes([b[4], b[5], b[6], b[7]]);
383 let qs = &b[8..24];
384 let x = |j: usize, q: u8| -> (f32, f32) {
385 let xh0 = (((qh >> j) << 4) & 0x10) as u8;
386 let xh1 = ((qh >> (j + 12)) & 0x10) as u8;
387 (
388 ((q & 0x0f) | xh0) as f32 * d + m,
389 ((q >> 4) | xh1) as f32 * d + m,
390 )
391 };
392 let (lo, hi): (Vec<f32>, Vec<f32>) = qs.iter().enumerate().map(|(j, &q)| x(j, q)).unzip();
393 y.extend(lo);
394 y.extend(hi);
395}
396
397fn q8_0(b: &[u8], y: &mut Vec<f32>) {
398 let d = half(b, 0);
399 y.extend(b[2..34].iter().map(|&q| (q as i8) as f32 * d));
400}
401
402pub const KVALUES_IQ4NL: [i8; 16] = [-127, -104, -83, -65, -49, -35, -22, -10, 1, 13, 25, 38, 53, 69, 89, 113];
404
405fn iq4_nl(b: &[u8], y: &mut Vec<f32>) {
406 let d = half(b, 0);
407 let qs = &b[2..18];
408 y.extend(qs.iter().map(|&q| d * KVALUES_IQ4NL[(q & 0x0f) as usize] as f32));
409 y.extend(qs.iter().map(|&q| d * KVALUES_IQ4NL[(q >> 4) as usize] as f32));
410}
411
412fn iq4_xs(b: &[u8], y: &mut Vec<f32>) {
413 let d = half(b, 0);
414 let scales_h = u16::from_le_bytes([b[2], b[3]]);
415 let scales_l = &b[4..8];
416 let qs = &b[8..136];
417 for ib in 0..QK_K / 32 {
418 let ls = ((scales_l[ib / 2] >> (4 * (ib % 2))) & 0xf) as i32 | ((((scales_h >> (2 * ib)) & 3) as i32) << 4);
419 let dl = d * (ls - 32) as f32;
420 let q = &qs[16 * ib..16 * ib + 16];
421 y.extend(q.iter().map(|&v| dl * KVALUES_IQ4NL[(v & 0x0f) as usize] as f32));
422 y.extend(q.iter().map(|&v| dl * KVALUES_IQ4NL[(v >> 4) as usize] as f32));
423 }
424}
425
426const KVALUES_MXFP4: [i8; 16] = [0, 1, 2, 3, 4, 6, 8, 12, 0, -1, -2, -3, -4, -6, -8, -12];
428
429fn e8m0_half(x: u8) -> f32 {
431 let bits = if x < 2 {
432 0x0020_0000u32 << x
433 } else {
434 ((x - 1) as u32) << 23
435 };
436 f32::from_bits(bits)
437}
438
439fn mxfp4(b: &[u8], y: &mut Vec<f32>) {
440 let d = e8m0_half(b[0]);
441 let qs = &b[1..17];
442 y.extend(qs.iter().map(|&q| KVALUES_MXFP4[(q & 0x0f) as usize] as f32 * d));
443 y.extend(qs.iter().map(|&q| KVALUES_MXFP4[(q >> 4) as usize] as f32 * d));
444}
445
446fn q2_k(b: &[u8], y: &mut Vec<f32>) {
447 let scales = &b[0..16];
448 let qs = &b[16..80];
449 let (d, min) = (half(b, 80), half(b, 82));
450 let mut is = 0;
451 for n in (0..QK_K).step_by(128) {
452 let q = &qs[n / 4..n / 4 + 32];
453 let mut shift = 0;
454 for _ in 0..4 {
455 for half_block in [0usize, 16] {
456 let sc = scales[is];
457 is += 1;
458 let (dl, ml) = (d * (sc & 0xf) as f32, min * (sc >> 4) as f32);
459 for l in 0..16 {
460 y.push(dl * (((q[l + half_block] >> shift) & 3) as i8) as f32 - ml);
461 }
462 }
463 shift += 2;
464 }
465 }
466}
467
468fn q3_k(b: &[u8], y: &mut Vec<f32>) {
469 let hm = &b[0..32];
470 let qs = &b[32..96];
471 let packed = &b[96..108];
472 let d_all = half(b, 108);
473 let (kmask1, kmask2) = (0x0303_0303u32, 0x0f0f_0f0fu32);
474 let mut aux = [0u32; 4];
475 for (k, a) in aux.iter_mut().take(3).enumerate() {
476 *a = u32::from_le_bytes([
477 packed[4 * k],
478 packed[4 * k + 1],
479 packed[4 * k + 2],
480 packed[4 * k + 3],
481 ]);
482 }
483 let tmp = aux[2];
484 aux[2] = ((aux[0] >> 4) & kmask2) | (((tmp >> 4) & kmask1) << 4);
485 aux[3] = ((aux[1] >> 4) & kmask2) | (((tmp >> 6) & kmask1) << 4);
486 aux[0] = (aux[0] & kmask2) | ((tmp & kmask1) << 4);
487 aux[1] = (aux[1] & kmask2) | (((tmp >> 2) & kmask1) << 4);
488 let scales: Vec<i8> = aux
489 .iter()
490 .flat_map(|a| a.to_le_bytes())
491 .map(|v| v as i8)
492 .collect();
493 let mut is = 0;
494 let mut m = 1u8;
495 for n in (0..QK_K).step_by(128) {
496 let q = &qs[n / 4..n / 4 + 32];
497 let mut shift = 0;
498 for _ in 0..4 {
499 for half_block in [0usize, 16] {
500 let dl = d_all * (scales[is] as i32 - 32) as f32;
501 is += 1;
502 for l in 0..16 {
503 let low = ((q[l + half_block] >> shift) & 3) as i8;
504 let high = if hm[l + half_block] & m != 0 { 0 } else { 4 };
505 y.push(dl * (low - high) as f32);
506 }
507 }
508 shift += 2;
509 m <<= 1;
510 }
511 }
512}
513
514fn scale_min_k4(j: usize, q: &[u8]) -> (u8, u8) {
516 if j < 4 {
517 (q[j] & 63, q[j + 4] & 63)
518 } else {
519 (
520 (q[j + 4] & 0xf) | ((q[j - 4] >> 6) << 4),
521 (q[j + 4] >> 4) | ((q[j] >> 6) << 4),
522 )
523 }
524}
525
526fn q4_k(b: &[u8], y: &mut Vec<f32>) {
527 let (d, min) = (half(b, 0), half(b, 2));
528 let scales = &b[4..16];
529 let qs = &b[16..144];
530 let mut is = 0;
531 for j in (0..QK_K).step_by(64) {
532 let q = &qs[j / 2..j / 2 + 32];
533 let (sc, m) = scale_min_k4(is, scales);
534 let (d1, m1) = (d * sc as f32, min * m as f32);
535 let (sc, m) = scale_min_k4(is + 1, scales);
536 let (d2, m2) = (d * sc as f32, min * m as f32);
537 y.extend(q.iter().map(|&v| d1 * (v & 0xf) as f32 - m1));
538 y.extend(q.iter().map(|&v| d2 * (v >> 4) as f32 - m2));
539 is += 2;
540 }
541}
542
543fn q5_k(b: &[u8], y: &mut Vec<f32>) {
544 let (d, min) = (half(b, 0), half(b, 2));
545 let scales = &b[4..16];
546 let qh = &b[16..48];
547 let qs = &b[48..176];
548 let mut is = 0;
549 let (mut u1, mut u2) = (1u8, 2u8);
550 for j in (0..QK_K).step_by(64) {
551 let ql = &qs[j / 2..j / 2 + 32];
552 let (sc, m) = scale_min_k4(is, scales);
553 let (d1, m1) = (d * sc as f32, min * m as f32);
554 let (sc, m) = scale_min_k4(is + 1, scales);
555 let (d2, m2) = (d * sc as f32, min * m as f32);
556 for l in 0..32 {
557 let hi = if qh[l] & u1 != 0 { 16 } else { 0 };
558 y.push(d1 * ((ql[l] & 0xf) as i32 + hi) as f32 - m1);
559 }
560 for l in 0..32 {
561 let hi = if qh[l] & u2 != 0 { 16 } else { 0 };
562 y.push(d2 * ((ql[l] >> 4) as i32 + hi) as f32 - m2);
563 }
564 is += 2;
565 u1 <<= 2;
566 u2 <<= 2;
567 }
568}
569
570fn q6_k(b: &[u8], y: &mut Vec<f32>) {
571 let ql_all = &b[0..128];
572 let qh_all = &b[128..192];
573 let sc_all: Vec<i8> = b[192..208].iter().map(|&v| v as i8).collect();
574 let d = half(b, 208);
575 let mut block = [0f32; QK_K];
576 for (part, n) in (0..QK_K).step_by(128).enumerate() {
577 let ql = &ql_all[part * 64..part * 64 + 64];
578 let qh = &qh_all[part * 32..part * 32 + 32];
579 let sc = &sc_all[part * 8..part * 8 + 8];
580 for l in 0..32 {
581 let is = l / 16;
582 let q1 = (((ql[l] & 0xf) | ((qh[l] & 3) << 4)) as i8) - 32;
583 let q2 = (((ql[l + 32] & 0xf) | (((qh[l] >> 2) & 3) << 4)) as i8) - 32;
584 let q3 = (((ql[l] >> 4) | (((qh[l] >> 4) & 3) << 4)) as i8) - 32;
585 let q4 = (((ql[l + 32] >> 4) | (((qh[l] >> 6) & 3) << 4)) as i8) - 32;
586 block[n + l] = d * sc[is] as f32 * q1 as f32;
587 block[n + l + 32] = d * sc[is + 2] as f32 * q2 as f32;
588 block[n + l + 64] = d * sc[is + 4] as f32 * q3 as f32;
589 block[n + l + 96] = d * sc[is + 6] as f32 * q4 as f32;
590 }
591 }
592 y.extend_from_slice(&block);
593}