Skip to content

Commit c43d35b

Browse files
committed
Add TurboQuant Vulkan turbo4 SET_ROWS support
1 parent e1adfd4 commit c43d35b

103 files changed

Lines changed: 23030 additions & 413 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

common/arg.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,9 @@ const std::vector<ggml_type> kv_cache_types = {
406406
GGML_TYPE_IQ4_NL,
407407
GGML_TYPE_Q5_0,
408408
GGML_TYPE_Q5_1,
409+
GGML_TYPE_TURBO2_0,
410+
GGML_TYPE_TURBO3_0,
411+
GGML_TYPE_TURBO4_0,
409412
};
410413

411414
static ggml_type kv_cache_type_from_str(const std::string & s) {

common/common.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@
4444
#include <string.h>
4545
#include <fcntl.h>
4646
#include <io.h>
47+
#ifndef fileno
48+
#define fileno _fileno
49+
#endif
50+
#ifndef isatty
51+
#define isatty _isatty
52+
#endif
4753
#else
4854
#include <sys/ioctl.h>
4955
#include <sys/stat.h>

ggml/include/ggml-rpc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
extern "C" {
77
#endif
88

9-
#define RPC_PROTO_MAJOR_VERSION 4
9+
#define RPC_PROTO_MAJOR_VERSION 5
1010
#define RPC_PROTO_MINOR_VERSION 0
1111
#define RPC_PROTO_PATCH_VERSION 0
1212

1313
#ifdef __cplusplus
14-
static_assert(GGML_OP_COUNT == 96, "GGML_OP_COUNT has changed - update RPC_PROTO_PATCH_VERSION");
14+
static_assert(GGML_OP_COUNT == 97, "GGML_OP_COUNT has changed - update RPC protocol version");
1515
#endif
1616

1717
#define GGML_RPC_MAX_SERVERS 16

ggml/include/ggml.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,12 @@ extern "C" {
429429
GGML_TYPE_MXFP4 = 39, // MXFP4 (1 block)
430430
GGML_TYPE_NVFP4 = 40, // NVFP4 (4 blocks, E4M3 scale)
431431
GGML_TYPE_Q1_0 = 41,
432-
GGML_TYPE_COUNT = 42,
432+
GGML_TYPE_TURBO2_0 = 42, // TurboQuant 2-bit KV cache: WHT + 2-bit PolarQuant
433+
GGML_TYPE_TURBO3_0 = 43, // TurboQuant 3-bit KV cache: WHT + 3-bit PolarQuant
434+
GGML_TYPE_TURBO4_0 = 44, // TurboQuant 4-bit KV cache: WHT + 4-bit PolarQuant
435+
GGML_TYPE_TQ3_1S = 45, // TurboQuant 3-bit weight: WHT-rotated 8-level Lloyd-Max, block_size=32
436+
GGML_TYPE_TQ4_1S = 46, // TurboQuant 4-bit weight: WHT-rotated 16-level Lloyd-Max, block_size=32
437+
GGML_TYPE_COUNT = 47,
433438
};
434439

435440
// precision
@@ -567,6 +572,7 @@ extern "C" {
567572
GGML_OP_RWKV_WKV7,
568573
GGML_OP_SOLVE_TRI,
569574
GGML_OP_GATED_DELTA_NET,
575+
GGML_OP_TURBO_WHT,
570576

571577
GGML_OP_UNARY,
572578

@@ -2555,6 +2561,16 @@ extern "C" {
25552561
struct ggml_tensor * beta,
25562562
struct ggml_tensor * state);
25572563

2564+
// TurboQuant Walsh-Hadamard Transform (O(d log d) rotation for KV cache compression)
2565+
// Applies WHT rotation to 128-element groups along ne[0]: sign1 → butterfly → sign2 → normalize
2566+
// direction: 0 = forward (signs1 → WHT → signs2), 1 = inverse (signs2 → WHT → signs1)
2567+
GGML_API struct ggml_tensor * ggml_turbo_wht(
2568+
struct ggml_context * ctx,
2569+
struct ggml_tensor * a,
2570+
int direction,
2571+
int group_size, // 0 = auto (64 or 128 from ne[0])
2572+
struct ggml_tensor * scale); // NULL = no InnerQ scaling
2573+
25582574
// custom operators
25592575

25602576
typedef void (*ggml_custom1_op_t)(struct ggml_tensor * dst , const struct ggml_tensor * a, int ith, int nth, void * userdata);

ggml/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ add_library(ggml-base
206206
ggml-threading.h
207207
ggml-quants.c
208208
ggml-quants.h
209+
ggml-turbo-quant.c
209210
gguf.cpp)
210211

211212
set_target_properties(ggml-base PROPERTIES

ggml/src/ggml-common.h

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,97 @@ typedef struct {
277277
} block_tq2_0;
278278
static_assert(sizeof(block_tq2_0) == sizeof(ggml_half) + QK_K / 4, "wrong tq2_0 block size/padding");
279279

280+
// TurboQuant 3-bit MSE-only: 3-bit PolarQuant indices (no QJL)
281+
// Storage block size = 32 (matches q4_0 for optimal GPU parallelism)
282+
// Transform group size = 128 (head_dim, for rotation Gaussianization)
283+
// Per block: norm(fp16) + 2-bit indices (8 bytes) + 1-bit extra (4 bytes) = 14 bytes per 32 values
284+
// = 3.5 bits/value → 4.6× compression vs fp16
285+
// The 3-bit index is split: lower 2 bits in qs[], upper 1 bit in signs[]
286+
#define QK_TURBO3 128 // Block size 128: one block per rotation group, eliminates redundant norms
287+
#define QK_TURBO3_GROUP 128 // rotation group size = head_dim
288+
// Derived: FA template nl parameters (auto-scale with block size)
289+
#define NL_TURBO3 (QK_TURBO3 / 16) // non-vec FA iterations per block
290+
#define NL_TURBO3_VEC (QK_TURBO3 / 4) // vec FA iterations per block
291+
typedef struct {
292+
ggml_half norm; // 2 bytes: vector L2 norm (for rescaling)
293+
uint8_t qs[QK_TURBO3 / 4]; // 8 bytes: lower 2-bit indices (4 per byte)
294+
uint8_t signs[QK_TURBO3 / 8]; // 4 bytes: upper 1-bit of 3-bit index (8 per byte)
295+
} block_turbo3_0; // 14 bytes total
296+
static_assert(sizeof(block_turbo3_0) == sizeof(ggml_half) + QK_TURBO3/4 + QK_TURBO3/8, "wrong turbo3_0 block size/padding");
297+
298+
// TurboQuant 4-bit: 3-bit PolarQuant indices + 1-bit QJL signs
299+
// TURBO4_USE_4BIT: switch between 4-bit PolarQuant (new) and 3-bit+QJL (legacy)
300+
// Default: 4-bit on all backends (Metal + CUDA validated)
301+
#ifndef TURBO4_USE_4BIT
302+
# define TURBO4_USE_4BIT 1
303+
#endif
304+
305+
#define QK_TURBO4 128
306+
307+
#if TURBO4_USE_4BIT
308+
// 4-bit PolarQuant: 16 optimal centroids, nibble packed, no QJL
309+
// Per block: norm(fp16) + rnorm(fp16, reserved) + 4-bit indices (64 bytes)
310+
// = 68 bytes per 128 values = 4.25 bits/value → 3.8× compression vs fp16
311+
typedef struct {
312+
ggml_half norm; // 2 bytes
313+
ggml_half rnorm; // 2 bytes (reserved, unused in 4-bit mode)
314+
uint8_t qs[QK_TURBO4 / 2]; // 64 bytes: 4-bit PolarQuant indices (nibble packed)
315+
} block_turbo4_0; // 68 bytes total
316+
static_assert(sizeof(block_turbo4_0) == 68, "wrong turbo4_0 block size");
317+
#else
318+
// Legacy 3-bit PolarQuant + 1-bit QJL (original paper design)
319+
// Per block: norm(fp16) + rnorm(fp16) + 3-bit indices (48 bytes) + 1-bit QJL signs (16 bytes)
320+
// = 68 bytes per 128 values = 4.25 bits/value → 3.8× compression vs fp16
321+
typedef struct {
322+
ggml_half norm; // 2 bytes
323+
ggml_half rnorm; // 2 bytes: residual norm for QJL scale
324+
uint8_t qs[QK_TURBO4 * 3 / 8]; // 48 bytes: 3-bit PolarQuant indices
325+
uint8_t signs[QK_TURBO4 / 8]; // 16 bytes: 1-bit QJL signs
326+
} block_turbo4_0; // 68 bytes total
327+
static_assert(sizeof(block_turbo4_0) == 2*sizeof(ggml_half) + QK_TURBO4*3/8 + QK_TURBO4/8, "wrong turbo4_0 block size");
328+
#endif
329+
330+
static_assert(QK_TURBO4 == 128, "turbo4 kernels assume QK_TURBO4 == 128");
331+
332+
// TurboQuant 2-bit: 2-bit PolarQuant indices only (no QJL)
333+
// Per block: norm(fp16) + 2-bit indices (8 bytes) = 10 bytes per 32 values
334+
// = 2.5 bits/value → 6.4× compression vs fp16
335+
// 4 centroids (Lloyd-Max for N(0, 1/128)): {-0.133462, -0.039994, 0.039994, 0.133462}
336+
#define QK_TURBO2 128 // Block size 128: one block per rotation group
337+
#define QK_TURBO2_GROUP 128 // rotation group size = head_dim
338+
// Derived: FA template nl parameters (auto-scale with block size)
339+
#define NL_TURBO2 (QK_TURBO2 / 16) // non-vec FA iterations per block
340+
#define NL_TURBO2_VEC (QK_TURBO2 / 4) // vec FA iterations per block
341+
typedef struct {
342+
ggml_half norm; // 2 bytes: corrected L2 norm
343+
uint8_t qs[QK_TURBO2 / 4]; // 8 bytes: 2-bit indices (4 per byte)
344+
} block_turbo2_0; // 10 bytes total
345+
static_assert(sizeof(block_turbo2_0) == sizeof(ggml_half) + QK_TURBO2/4, "wrong turbo2_0 block size/padding");
346+
347+
// TQ3_1S: WHT-rotated 3-bit weight quantization (8-level Lloyd-Max for N(0,1))
348+
// Block size 32, dual half-block scales (d0 for [0..15], d1 for [16..31])
349+
// Per block: d0(fp16) + d1(fp16) + 3-bit indices packed (12 bytes) = 16 bytes per 32 values
350+
// = 4.0 bits/value
351+
#define QK_TQ3_0 32
352+
typedef struct {
353+
ggml_half d0; // 2 bytes: scale for first 16 elements
354+
ggml_half d1; // 2 bytes: scale for last 16 elements
355+
uint8_t qs[QK_TQ3_0 * 3 / 8]; // 12 bytes: 3-bit indices packed (4 groups of 8 in 3 bytes)
356+
} block_tq3_1s; // 16 bytes total
357+
static_assert(sizeof(block_tq3_1s) == 16, "wrong tq3_1s block size");
358+
359+
// TQ4_1S: WHT-rotated 4-bit weight quantization (16-level Lloyd-Max for N(0,1))
360+
// Block size 32, dual half-block scales (d0 for [0..15], d1 for [16..31])
361+
// Per block: d0(fp16) + d1(fp16) + 4-bit indices packed (16 bytes) = 20 bytes per 32 values
362+
// = 5.0 bits/value
363+
#define QK_TQ4_1S 32
364+
typedef struct {
365+
ggml_half d0; // 2 bytes: scale for first 16 elements
366+
ggml_half d1; // 2 bytes: scale for last 16 elements
367+
uint8_t qs[QK_TQ4_1S / 2]; // 16 bytes: 4-bit indices nibble-packed
368+
} block_tq4_1s; // 20 bytes total
369+
static_assert(sizeof(block_tq4_1s) == 20, "wrong tq4_1s block size");
370+
280371
//
281372
// Super-block quantization structures
282373
//

0 commit comments

Comments
 (0)